#!/bin/sh
set -e
REPO="Atro-Tech/nowbox"
CACHE_DIR="${NOWBOX_CACHE_DIR:-$HOME/.cache/nowbox}"
INSTALL_DIR="${NOWBOX_INSTALL_DIR:-/usr/local/bin}"
# Platform detection
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
case "$ARCH" in
x86_64) ARCH="amd64" ;;
aarch64) ARCH="arm64" ;;
esac
EXT=""
case "$OS" in
mingw*|msys*|cygwin*|windows*)
OS="windows"
EXT=".exe"
;;
esac
NAME="nowbox-${OS}-${ARCH}${EXT}"
BINARY="$CACHE_DIR/nowbox${EXT}"
BASE_URL="https://github.com/${REPO}/releases/latest/download"
# Download tool
if command -v curl >/dev/null 2>&1; then
FETCH="curl -fsSL"
elif command -v wget >/dev/null 2>&1; then
FETCH="wget -qO-"
else
echo "nowbox: error: curl or wget required" >&2
exit 1
fi
download_binary() {
echo "nowbox: downloading..." >&2
mkdir -p "$CACHE_DIR"
TMP="$CACHE_DIR/.nowbox-download-$$"
$FETCH "${BASE_URL}/${NAME}" > "$TMP" 2>/dev/null || {
echo "nowbox: download failed" >&2
echo "nowbox: try: ${BASE_URL}/${NAME}" >&2
rm -f "$TMP"
exit 1
}
# Verify checksum
EXPECTED=$($FETCH "${BASE_URL}/${NAME}.sha256" 2>/dev/null | awk '{print $1}')
if [ -n "$EXPECTED" ]; then
if command -v sha256sum >/dev/null 2>&1; then
ACTUAL=$(sha256sum "$TMP" | awk '{print $1}')
elif command -v shasum >/dev/null 2>&1; then
ACTUAL=$(shasum -a 256 "$TMP" | awk '{print $1}')
else
ACTUAL="$EXPECTED"
fi
if [ "$ACTUAL" != "$EXPECTED" ]; then
echo "nowbox: checksum mismatch" >&2
rm -f "$TMP"
exit 1
fi
echo "nowbox: verified" >&2
fi
chmod +x "$TMP"
echo "$TMP"
}
# ── Install mode ──
if [ "$1" = "install" ]; then
echo "nowbox: installing..." >&2
TMP=$(download_binary)
if [ "$OS" = "darwin" ]; then
# macOS: create .app bundle in /Applications
APP_DIR="/Applications/nowbox.app"
mkdir -p "$APP_DIR/Contents/MacOS"
mkdir -p "$APP_DIR/Contents/Resources"
# Copy binary
cp "$TMP" "$APP_DIR/Contents/MacOS/nowbox-bin"
chmod +x "$APP_DIR/Contents/MacOS/nowbox-bin"
# Launcher script — opens Terminal with nowbox
cat > "$APP_DIR/Contents/MacOS/nowbox" << 'LAUNCHER'
#!/bin/sh
DIR="$(dirname "$0")"
if [ -t 1 ]; then
exec "$DIR/nowbox-bin" "$@"
else
osascript -e "tell application \"Terminal\" to do script \"'$DIR/nowbox-bin'\""
osascript -e "tell application \"Terminal\" to activate"
fi
LAUNCHER
chmod +x "$APP_DIR/Contents/MacOS/nowbox"
# Info.plist
cat > "$APP_DIR/Contents/Info.plist" << 'PLIST'
CFBundleExecutable
nowbox
CFBundleIdentifier
lol.nowbox.app
CFBundleName
nowbox
CFBundleDisplayName
nowbox
CFBundleVersion
0.1.0
CFBundleShortVersionString
0.1.0
CFBundlePackageType
APPL
CFBundleIconFile
icon
LSMinimumSystemVersion
11.0
CFBundleDocumentTypes
CFBundleTypeExtensions
now
CFBundleTypeName
nowbox session
CFBundleTypeRole
Editor
PLIST
# Generate icon from SVG using sips (macOS built-in)
# Create a simple 512x512 PNG icon
cat > "$CACHE_DIR/icon.svg" << 'ICONSVG'
ICONSVG
# Convert SVG to ICNS if possible
if command -v rsvg-convert >/dev/null 2>&1; then
rsvg-convert -w 512 -h 512 "$CACHE_DIR/icon.svg" -o "$CACHE_DIR/icon.png"
elif command -v qlmanage >/dev/null 2>&1; then
# Use macOS Quick Look to render
qlmanage -t -s 512 -o "$CACHE_DIR" "$CACHE_DIR/icon.svg" 2>/dev/null || true
[ -f "$CACHE_DIR/icon.svg.png" ] && mv "$CACHE_DIR/icon.svg.png" "$CACHE_DIR/icon.png"
fi
if [ -f "$CACHE_DIR/icon.png" ]; then
# Create iconset and convert to icns
ICONSET="$CACHE_DIR/icon.iconset"
mkdir -p "$ICONSET"
sips -z 16 16 "$CACHE_DIR/icon.png" --out "$ICONSET/icon_16x16.png" 2>/dev/null
sips -z 32 32 "$CACHE_DIR/icon.png" --out "$ICONSET/icon_16x16@2x.png" 2>/dev/null
sips -z 32 32 "$CACHE_DIR/icon.png" --out "$ICONSET/icon_32x32.png" 2>/dev/null
sips -z 64 64 "$CACHE_DIR/icon.png" --out "$ICONSET/icon_32x32@2x.png" 2>/dev/null
sips -z 128 128 "$CACHE_DIR/icon.png" --out "$ICONSET/icon_128x128.png" 2>/dev/null
sips -z 256 256 "$CACHE_DIR/icon.png" --out "$ICONSET/icon_128x128@2x.png" 2>/dev/null
sips -z 256 256 "$CACHE_DIR/icon.png" --out "$ICONSET/icon_256x256.png" 2>/dev/null
sips -z 512 512 "$CACHE_DIR/icon.png" --out "$ICONSET/icon_256x256@2x.png" 2>/dev/null
cp "$CACHE_DIR/icon.png" "$ICONSET/icon_512x512.png"
iconutil -c icns -o "$APP_DIR/Contents/Resources/icon.icns" "$ICONSET" 2>/dev/null
rm -rf "$ICONSET" "$CACHE_DIR/icon.png" "$CACHE_DIR/icon.svg"
fi
# Also install CLI to PATH
if [ -w "$INSTALL_DIR" ]; then
cp "$TMP" "$INSTALL_DIR/nowbox"
elif mkdir -p "$HOME/.local/bin" 2>/dev/null; then
cp "$TMP" "$HOME/.local/bin/nowbox"
fi
rm -f "$TMP"
# Register .now file association
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f "$APP_DIR" 2>/dev/null || true
echo "nowbox: installed to /Applications/nowbox.app" >&2
echo "nowbox: .now files will open with nowbox" >&2
echo "nowbox: run: nowbox" >&2
else
# Linux/other: install to PATH
if [ -w "$INSTALL_DIR" ]; then
mv "$TMP" "$INSTALL_DIR/nowbox${EXT}"
echo "nowbox: installed to $INSTALL_DIR/nowbox" >&2
elif mkdir -p "$HOME/.local/bin" 2>/dev/null; then
mv "$TMP" "$HOME/.local/bin/nowbox${EXT}"
echo "nowbox: installed to ~/.local/bin/nowbox" >&2
case "$PATH" in
*"$HOME/.local/bin"*) ;;
*) echo "nowbox: add ~/.local/bin to your PATH" >&2 ;;
esac
else
echo "nowbox: cannot install — try with sudo" >&2
rm -f "$TMP"
exit 1
fi
fi
echo "nowbox: done" >&2
exit 0
fi
# ── Normal mode: download to cache and run ──
if [ -x "$BINARY" ]; then
exec "$BINARY" "$@" &2
exec "$BINARY" "$@"