From bec31bfbd16592ccf38728cdd7d385147af647f7 Mon Sep 17 00:00:00 2001 From: akrupa-appto Date: Wed, 2 Sep 2026 08:19:46 +0000 Subject: [PATCH] Install vcx into its own directory instead of Bun's global manifest Bun 1.4.0 refuses the global install on some machines with 'refusing to install dependency with unsafe name' once the global manifest carries entries from earlier installs. install.sh now installs vcx and Vercel CLI into ~/.vcx with a fresh manifest and links the bins into Bun's bin dir. Co-Authored-By: Claude Fable 5.1 --- CHANGELOG.md | 7 +++++++ README.md | 8 ++++++-- install.sh | 54 ++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a1362e..8811e27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## Unreleased + +- `install.sh` installs into `~/.vcx` with a fresh manifest instead of + `bun install --global`. Bun 1.4.0 fails with `refusing to install dependency + with unsafe name` on some machines when the global manifest carries entries + from earlier installs, and the new path does not depend on that state. + ## 0.3.0 - 2026-09-02 - Link Vercel's global config directory to the active profile, so a plain diff --git a/README.md b/README.md index 7f79c62..011a925 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,12 @@ One line. It installs Bun if you do not have it, then Vercel CLI and vcx. curl -fsSL https://raw.githubusercontent.com/akrupa-appto/vcx/main/install.sh | sh ``` -Set `VCX_REF` to pick a tag, branch, or commit instead of the latest release. -You still need Node.js 20 or newer, because Vercel CLI runs on Node. +The script keeps vcx and its dependencies in `~/.vcx` with their own lockfile +and links `vcx` into Bun's bin directory. It does not touch Bun's global +package list, so a broken global manifest cannot block it. Run it again to +upgrade. Set `VCX_REF` to pick a tag, branch, or commit instead of the latest +release, and `VCX_INSTALL_DIR` to move the directory. You still need Node.js +20 or newer, because Vercel CLI runs on Node. Already have Bun? Install directly: diff --git a/install.sh b/install.sh index 52f800f..12381db 100755 --- a/install.sh +++ b/install.sh @@ -2,13 +2,19 @@ # Installs vcx with Bun. Usage: # curl -fsSL https://raw.githubusercontent.com/akrupa-appto/vcx/main/install.sh | sh # +# vcx lives in its own directory (default ~/.vcx) with its own lockfile, so a +# broken Bun global manifest cannot block the install. Bin links go into +# Bun's bin directory, which is already on PATH for Bun users. +# # Environment: -# VCX_REF Git ref to install (tag, branch, or commit). Default: latest release. -# BUN_INSTALL Where Bun lives or gets installed. Default: ~/.bun +# VCX_REF Git ref to install (tag, branch, or commit). Default: latest release. +# VCX_INSTALL_DIR Where vcx and its dependencies live. Default: ~/.vcx +# BUN_INSTALL Where Bun lives or gets installed. Default: ~/.bun set -eu REPO="akrupa-appto/vcx" BUN_INSTALL="${BUN_INSTALL:-$HOME/.bun}" +VCX_INSTALL_DIR="${VCX_INSTALL_DIR:-$HOME/.vcx}" say() { printf '%s\n' "$*"; } fail() { say "vcx install: $*" >&2; exit 1; } @@ -32,26 +38,46 @@ else [ -x "$BUN" ] || fail "Bun install did not produce $BUN." fi say "Using Bun $("$BUN" --version) at $BUN" +# Bun's global bin directory, the one Bun users already have on PATH. +BIN_DIR="$(HOME="$HOME" "$BUN" pm bin --global 2>/dev/null || true)" +[ -n "$BIN_DIR" ] || BIN_DIR="$BUN_INSTALL/bin" -# 2. Vercel CLI, which vcx wraps -if ! command -v vercel >/dev/null 2>&1; then - say "Installing Vercel CLI ..." - "$BUN" install --global vercel >/dev/null -fi - -# 3. vcx itself. The github: form avoids Bun 1.4.0's false "unsafe name" error on tarballs. +# 2. Resolve the vcx ref. The github: form avoids Bun 1.4.0's false +# "unsafe name" error on remote tarballs. REF="${VCX_REF:-}" if [ -z "$REF" ]; then REF="$(curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" 2>/dev/null \ | sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p' | head -n 1)" [ -n "$REF" ] || REF="main" fi -say "Installing vcx ($REF) ..." -"$BUN" install --global "github:$REPO#$REF" >/dev/null -# 4. Verify -BIN_DIR="$("$BUN" pm bin --global 2>/dev/null || printf '%s' "$BUN_INSTALL/bin")" -[ -x "$BIN_DIR/vcx" ] || fail "expected $BIN_DIR/vcx after install." +# 3. Install vcx and Vercel CLI into a private directory with a fresh manifest. +say "Installing vcx ($REF) into $VCX_INSTALL_DIR ..." +mkdir -p "$VCX_INSTALL_DIR" +cat > "$VCX_INSTALL_DIR/package.json" </dev/null) + +VCX_BIN="$VCX_INSTALL_DIR/node_modules/vcx-cli/dist/cli.js" +[ -f "$VCX_BIN" ] || fail "expected $VCX_BIN after install." +chmod 755 "$VCX_BIN" + +# 4. Bin links. vcx always. vercel only when nothing on PATH provides it. +mkdir -p "$BIN_DIR" +ln -sf "$VCX_BIN" "$BIN_DIR/vcx" +if ! command -v vercel >/dev/null 2>&1; then + ln -sf "$VCX_INSTALL_DIR/node_modules/vercel/dist/vc.js" "$BIN_DIR/vercel" +fi + say "Installed vcx $("$BIN_DIR/vcx" --version)" if ! command -v vcx >/dev/null 2>&1; then