#!/usr/bin/env sh # VidBee CLI standalone installer. # # curl -fsSL https://vidbee.dev/cli/install.sh | sh # curl -fsSL https://vidbee.dev/cli/install.sh | sh -s -- --version 0.1.0 # # Downloads the npm tarball for `@vidbee/cli` and installs it under # $VIDBEE_HOME (default ~/.vidbee/cli). Writes a `vidbee` shim into # $VIDBEE_BIN_DIR (default ~/.local/bin) that runs the bundled CLI via # Node ≥ 20. # # Designed to work on macOS and Linux with POSIX sh + curl + tar + node. # Windows users should install via npm: npm install -g @vidbee/cli # # Reference: NEX-148 §2. set -eu PKG_NAME="@vidbee/cli" REGISTRY_URL="${VIDBEE_REGISTRY:-https://registry.npmjs.org}" VIDBEE_HOME="${VIDBEE_HOME:-$HOME/.vidbee/cli}" VIDBEE_BIN_DIR="${VIDBEE_BIN_DIR:-$HOME/.local/bin}" VERSION="" QUIET="${VIDBEE_QUIET:-0}" log() { if [ "$QUIET" != "1" ]; then printf '%s\n' "$1" >&2 fi } die() { printf 'vidbee install: %s\n' "$1" >&2 exit 1 } while [ $# -gt 0 ]; do case "$1" in --version) shift [ $# -gt 0 ] || die '--version requires a value' VERSION="$1" ;; --version=*) VERSION="${1#--version=}" ;; --bin-dir) shift [ $# -gt 0 ] || die '--bin-dir requires a value' VIDBEE_BIN_DIR="$1" ;; --bin-dir=*) VIDBEE_BIN_DIR="${1#--bin-dir=}" ;; --home) shift [ $# -gt 0 ] || die '--home requires a value' VIDBEE_HOME="$1" ;; --home=*) VIDBEE_HOME="${1#--home=}" ;; --quiet) QUIET=1 ;; --help|-h) cat </dev/null 2>&1 || die "missing required command: $1" } need curl need tar need node NODE_MAJOR="$(node -p 'process.versions.node.split(".")[0]' 2>/dev/null || echo 0)" if [ "$NODE_MAJOR" -lt 20 ]; then die "node ≥ 20 required (found $(node -v 2>/dev/null || echo 'none'))" fi # Resolve version if [ -z "$VERSION" ]; then log "Resolving latest version of $PKG_NAME from $REGISTRY_URL" META_URL="$REGISTRY_URL/$(printf '%s' "$PKG_NAME" | sed 's|/|%2F|')/latest" RESOLVED="$(curl -fsSL "$META_URL" | node -e ' let buf = ""; process.stdin.on("data", (c) => { buf += c; }); process.stdin.on("end", () => { const data = JSON.parse(buf); if (typeof data.version !== "string") { process.stderr.write("registry response missing version\n"); process.exit(1); } process.stdout.write(data.version); }); ')" VERSION="$RESOLVED" [ -n "$VERSION" ] || die "could not resolve latest version" fi log "Installing $PKG_NAME@$VERSION → $VIDBEE_HOME" TMP_DIR="$(mktemp -d 2>/dev/null || mktemp -d -t vidbee)" trap 'rm -rf "$TMP_DIR"' EXIT INT TERM ESCAPED_NAME="$(printf '%s' "$PKG_NAME" | sed 's|/|%2F|')" META_URL="$REGISTRY_URL/$ESCAPED_NAME/$VERSION" META_FILE="$TMP_DIR/meta.json" curl -fsSL "$META_URL" -o "$META_FILE" || die "could not fetch package metadata" TARBALL_URL="$(node -e ' const fs = require("node:fs"); const m = JSON.parse(fs.readFileSync(process.argv[1], "utf-8")); if (!m || !m.dist || !m.dist.tarball) { process.stderr.write("metadata missing dist.tarball\n"); process.exit(1); } process.stdout.write(m.dist.tarball); ' "$META_FILE")" [ -n "$TARBALL_URL" ] || die "metadata missing dist.tarball" TARBALL="$TMP_DIR/cli.tgz" curl -fsSL "$TARBALL_URL" -o "$TARBALL" || die "could not download tarball" mkdir -p "$VIDBEE_HOME" # Replace any prior install atomically by extracting into a new dir then # swapping it in. STAGING="$TMP_DIR/staging" mkdir -p "$STAGING" tar -xf "$TARBALL" -C "$STAGING" [ -d "$STAGING/package" ] || die "unexpected tarball layout" rm -rf "$VIDBEE_HOME.old" if [ -d "$VIDBEE_HOME" ] && [ "$(ls -A "$VIDBEE_HOME" 2>/dev/null || true)" ]; then mv "$VIDBEE_HOME" "$VIDBEE_HOME.old" fi mkdir -p "$VIDBEE_HOME" # Move package contents into VIDBEE_HOME ( cd "$STAGING/package" && tar -cf - . ) | ( cd "$VIDBEE_HOME" && tar -xf - ) rm -rf "$VIDBEE_HOME.old" # Write the bin shim mkdir -p "$VIDBEE_BIN_DIR" SHIM="$VIDBEE_BIN_DIR/vidbee" cat >"$SHIM" <