1#!/bin/sh
2set -eu
3umask 077
4server=__SERVER__
5
6install_agent() {
7 [ "$(id -u)" != 0 ] || { echo 'Run this installer as your login user, without sudo.' >&2; return 1; }
8 case $(uname -s) in
9 Linux) os=linux; base=${XDG_DATA_HOME:-"$HOME/.local/share"}/agent-relay
10 command -v systemctl >/dev/null || { echo 'This installer needs a systemd user session.' >&2; return 1; }
11 systemctl --user show-environment >/dev/null || { echo 'Sign in to a systemd user session, then run the installer again.' >&2; return 1; } ;;
12 Darwin) os=darwin; base="$HOME/Library/Application Support/AgentRelay" ;;
13 *) echo "Use $server/agent/install.ps1 from Windows PowerShell." >&2; return 1 ;;
14 esac
15 case $(uname -m) in
16 x86_64|amd64) arch=x64 ;;
17 aarch64|arm64) arch=arm64 ;;
18 *) echo 'This installer supports x64 and arm64 machines.' >&2; return 1 ;;
19 esac
20 command -v curl >/dev/null || { echo 'Install curl, then run this installer again.' >&2; return 1; }
21 mkdir -p "$base"
22 chmod 700 "$base"
23 stage=$(mktemp -d "$base/.install.XXXXXX")
24 trap 'rm -rf "$stage"' EXIT HUP INT TERM
25 if [ ! -x "$base/node" ] && [ -f /etc/NIXOS ]; then
26 echo 'Installing the agent runtime…'
27 nix --extra-experimental-features 'nix-command flakes' build nixpkgs#nodejs_24 --out-link "$base/node-runtime"
28 ln -sf "$base/node-runtime/bin/node" "$base/node"
29 elif [ ! -x "$base/node" ]; then
30 echo 'Downloading the agent runtime…'
31 curl -fsSL https://nodejs.org/dist/latest-v24.x/SHASUMS256.txt -o "$stage/checksums"
32 archive=$(awk -v suffix="-$os-$arch.tar.gz" '$2 ~ /^node-v24\./ && substr($2, length($2)-length(suffix)+1) == suffix {print $2}' "$stage/checksums")
33 [ -n "$archive" ] || { echo 'No runtime download is available for this machine.' >&2; return 1; }
34 version=${archive#node-}; version=${version%%-$os-*}
35 curl -fsSL "https://nodejs.org/dist/$version/$archive" -o "$stage/$archive"
36 expected=$(awk -v file="$archive" '$2 == file {print $1}' "$stage/checksums")
37 if command -v sha256sum >/dev/null; then
38 actual=$(sha256sum "$stage/$archive"); actual=${actual%% *}
39 else
40 actual=$(shasum -a 256 "$stage/$archive"); actual=${actual%% *}
41 fi
42 [ "$actual" = "$expected" ] || { echo 'The runtime checksum did not match. Run the installer again.' >&2; return 1; }
43 tar -xzf "$stage/$archive" -C "$stage"
44 cp "$stage/${archive%.tar.gz}/bin/node" "$base/node"
45 chmod 700 "$base/node"
46 fi
47 curl -fsSL "$server/agent/relay.mjs" -o "$stage/relay.mjs"
48 curl -fsSL "$server/agent/setup.mjs" -o "$stage/setup.mjs"
49 "$base/node" "$stage/setup.mjs" install "$server" "$base" </dev/tty
50}
51
52# The shell must read the whole script before the installer opens the terminal.
53install_agent