From 321dabc04d5dbef12520a166365bfc59f36e93df Mon Sep 17 00:00:00 2001 From: ZanzyTHEbar Date: Wed, 18 Feb 2026 11:34:04 +0000 Subject: [PATCH 1/5] feat: add cursor shim and ensure-shim on install/update - shim.sh: ~/.local/bin/cursor shim that finds real cursor or delegates to cursor-installer - scripts/ensure-shim.sh: detect existing shim, skip if already current, else install/update - install.sh: sync shim + ensure-shim, run helper after placing CLI - cursor.sh: refresh shim assets from GitHub on update; ensure_shim before install --- cursor.sh | 42 ++++++++++++++++++++++++ install.sh | 39 ++++++++++++++++++++++ scripts/ensure-shim.sh | 73 ++++++++++++++++++++++++++++++++++++++++++ shim.sh | 46 ++++++++++++++++++++++++++ 4 files changed, 200 insertions(+) create mode 100644 scripts/ensure-shim.sh create mode 100644 shim.sh diff --git a/cursor.sh b/cursor.sh index a8cc712..5631e9a 100755 --- a/cursor.sh +++ b/cursor.sh @@ -21,6 +21,14 @@ fi CLI_NAME="cursor-installer" CLI_BIN="$HOME/.local/bin/$CLI_NAME" +REPO_OWNER=${REPO_OWNER:-watzon} +REPO_BRANCH=${REPO_BRANCH:-main} +REPO_NAME=${REPO_NAME:-cursor-linux-installer} +BASE_RAW_URL="https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/${REPO_BRANCH}" +SHARED_SHIM="$LIB_DIR/shim.sh" +SHIM_URL="$BASE_RAW_URL/shim.sh" +SHIM_HELPER="$LIB_DIR/ensure-shim.sh" +SHIM_HELPER_URL="$BASE_RAW_URL/scripts/ensure-shim.sh" # Installation mode: 'appimage' (default) or 'extracted' # Can be set via CURSOR_INSTALL_MODE environment variable or --extract flag @@ -47,6 +55,37 @@ function get_extraction_dir() { echo "$HOME/.local/share/cursor" } +function ensure_shim() { + if [ -x "$SHIM_HELPER" ]; then + if ! "$SHIM_HELPER"; then + log_warn "Shim update failed; continuing." + fi + return 0 + fi + if [ -f "$SHIM_HELPER" ]; then + if ! sh "$SHIM_HELPER"; then + log_warn "Shim update failed; continuing." + fi + return 0 + fi + log_info "Shim helper not found; skipping shim update." + return 0 +} + +function refresh_shim_assets() { + log_step "Refreshing cursor shim assets..." + mkdir -p "$LIB_DIR" + if ! curl -fsSL "$SHIM_URL" -o "$SHARED_SHIM"; then + log_warn "Failed to download shim.sh; continuing." + return 0 + fi + if ! curl -fsSL "$SHIM_HELPER_URL" -o "$SHIM_HELPER"; then + log_warn "Failed to download ensure-shim.sh; continuing." + return 0 + fi + chmod +x "$SHIM_HELPER" "$SHARED_SHIM" || true +} + function check_fuse() { # First, check if FUSE is already available if fusermount -V >/dev/null 2>&1; then @@ -289,6 +328,7 @@ EOF } function install_cursor_extracted() { + ensure_shim local install_dir="$1" local release_track=${2:-stable} local temp_file @@ -438,6 +478,7 @@ function install_cursor_extracted() { } function install_cursor() { + ensure_shim local install_dir="$1" local release_track=${2:-stable} # Default to stable if not specified @@ -663,6 +704,7 @@ EOF function update_cursor() { log_step "Updating Cursor..." + refresh_shim_assets local current_appimage current_appimage=$(find_cursor_appimage || true) local install_dir diff --git a/install.sh b/install.sh index f00d098..dc5b624 100755 --- a/install.sh +++ b/install.sh @@ -43,6 +43,12 @@ LIB_DIR="$HOME/.local/share/cursor-installer" LIB_PATH="$SCRIPT_DIR/lib.sh" SHARED_LIB="$LIB_DIR/lib.sh" LIB_URL="$BASE_RAW_URL/lib.sh" +SHIM_PATH="$SCRIPT_DIR/shim.sh" +SHARED_SHIM="$LIB_DIR/shim.sh" +SHIM_URL="$BASE_RAW_URL/shim.sh" +SHIM_HELPER_LOCAL="$SCRIPT_DIR/scripts/ensure-shim.sh" +SHIM_HELPER="$LIB_DIR/ensure-shim.sh" +SHIM_HELPER_URL="$BASE_RAW_URL/scripts/ensure-shim.sh" # Source shared helpers (local repo, installed lib, or download) if [ -f "$LIB_PATH" ]; then @@ -96,6 +102,39 @@ chmod +x "$CLI_PATH" log_ok "Cursor installer script has been placed in $CLI_PATH" +log_step "Ensuring cursor shim..." +SHIM_READY=true +if [ -f "$SHIM_PATH" ]; then + cp "$SHIM_PATH" "$SHARED_SHIM" +elif [ -f "$SHARED_SHIM" ]; then + : +else + log_info "Downloading shim.sh from GitHub..." + if ! curl -fsSL "$SHIM_URL" -o "$SHARED_SHIM"; then + log_warn "Failed to download shim.sh; shim update skipped." + SHIM_READY=false + fi +fi + +if [ "$SHIM_READY" = true ]; then + if [ -f "$SHIM_HELPER_LOCAL" ]; then + cp "$SHIM_HELPER_LOCAL" "$SHIM_HELPER" + else + log_info "Downloading ensure-shim.sh from GitHub..." + if ! curl -fsSL "$SHIM_HELPER_URL" -o "$SHIM_HELPER"; then + log_warn "Failed to download ensure-shim.sh; shim update skipped." + SHIM_READY=false + fi + fi +fi + +if [ "$SHIM_READY" = true ]; then + chmod +x "$SHIM_HELPER" "$SHARED_SHIM" || true + if ! "$SHIM_HELPER"; then + log_warn "Shim update failed; continuing installation." + fi +fi + # Check if ~/.local/bin is in PATH if [[ ":$PATH:" != *":$LOCAL_BIN:"* ]]; then log_warn "$LOCAL_BIN is not in your PATH." diff --git a/scripts/ensure-shim.sh b/scripts/ensure-shim.sh new file mode 100644 index 0000000..9d805f7 --- /dev/null +++ b/scripts/ensure-shim.sh @@ -0,0 +1,73 @@ +#!/bin/sh +# Install or update ~/.local/bin/cursor shim. Skips if existing file is already our shim. +set -eu + +TARGET_SHIM="${TARGET_SHIM:-$HOME/.local/bin/cursor}" +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) +LIB_DIR="${HOME}/.local/share/cursor-installer" + +SOURCE_SHIM="${SOURCE_SHIM:-}" +if [ -z "$SOURCE_SHIM" ]; then + if [ -f "$LIB_DIR/shim.sh" ]; then + SOURCE_SHIM="$LIB_DIR/shim.sh" + elif [ -f "$SCRIPT_DIR/shim.sh" ]; then + SOURCE_SHIM="$SCRIPT_DIR/shim.sh" + elif [ -f "$SCRIPT_DIR/../shim.sh" ]; then + SOURCE_SHIM="$SCRIPT_DIR/../shim.sh" + fi +fi + +if [ -z "$SOURCE_SHIM" ] || [ ! -f "$SOURCE_SHIM" ]; then + echo "Error: shim.sh source not found." >&2 + exit 1 +fi + +is_shim() { + file="$1" + [ -f "$file" ] || return 1 + first_line=$(head -n 1 "$file" 2>/dev/null || true) + case "$first_line" in + "#!/bin/sh"|\ + "#!/usr/bin/env sh"|\ + "#!/bin/bash"|\ + "#!/usr/bin/env bash") + ;; + *) + return 1 + ;; + esac + if grep -q "Find cursor executable in PATH" "$file" 2>/dev/null; then + return 0 + fi + if grep -q "cursor-installer" "$file" 2>/dev/null; then + return 0 + fi + return 1 +} + +is_current_shim() { + is_shim "$TARGET_SHIM" || return 1 + cmp -s "$SOURCE_SHIM" "$TARGET_SHIM" +} + +if is_current_shim; then + echo "Cursor shim already installed; skipping." + exit 0 +fi + +if [ ! -e "$TARGET_SHIM" ]; then + mkdir -p "$(dirname "$TARGET_SHIM")" + cp "$SOURCE_SHIM" "$TARGET_SHIM" + chmod +x "$TARGET_SHIM" + echo "Installed cursor shim at $TARGET_SHIM" + exit 0 +fi + +if ! is_shim "$TARGET_SHIM"; then + echo "Skipping shim update; existing cursor is not a shim: $TARGET_SHIM" + exit 0 +fi + +cp "$SOURCE_SHIM" "$TARGET_SHIM" +chmod +x "$TARGET_SHIM" +echo "Updated cursor shim at $TARGET_SHIM" diff --git a/shim.sh b/shim.sh new file mode 100644 index 0000000..001bf49 --- /dev/null +++ b/shim.sh @@ -0,0 +1,46 @@ +#!/bin/sh +set -eu + +# Find cursor executable in PATH, excluding the current shim +find_cursor() { + old_IFS="$IFS" + IFS=: + for dir in $PATH; do + [ -n "$dir" ] || continue + cursor_path="$dir/cursor" + if [ "$cursor_path" != "$HOME/.local/bin/cursor" ] && [ -x "$cursor_path" ]; then + IFS="$old_IFS" + echo "$cursor_path" + return 0 + fi + done + IFS="$old_IFS" + return 1 +} + +OTHER_CURSOR=$(find_cursor || true) +CURSOR_INSTALLER=$(command -v cursor-installer 2>/dev/null || true) +AGENT_BIN="$HOME/.local/bin/agent" + +if [ -n "${OTHER_CURSOR:-}" ]; then + exec "$OTHER_CURSOR" "$@" +fi + +first_arg="${1:-}" + +if [ "$first_arg" = "agent" ]; then + if [ -x "$AGENT_BIN" ]; then + exec "$AGENT_BIN" "$@" + fi + echo "Error: Cursor agent not found at $AGENT_BIN" 1>&2 + exit 1 +fi + +if [ -n "${CURSOR_INSTALLER:-}" ]; then + exec "$CURSOR_INSTALLER" "$@" +fi + +echo "Error: No Cursor IDE installation found." 1>&2 +echo "Install/update with: cursor-installer --update [stable|latest]" 1>&2 +echo "Or, install Cursor at https://cursor.com/download" 1>&2 +exit 1 From dd6e4bc096e15fc7db08cd45658ea5bc2badb486 Mon Sep 17 00:00:00 2001 From: ZanzyTHEbar Date: Wed, 18 Feb 2026 12:11:11 +0000 Subject: [PATCH 2/5] refactor(lib): add shim path constants and shared helpers - REPO_*, BASE_RAW_URL, SHIM_TARGET, SHARED_SHIM, SHIM_HELPER, URLs - sync_shim_assets(): copy or fetch shim.sh + ensure-shim.sh into LIB_DIR - refresh_shim_assets(): re-download from GitHub (for --update) - run_ensure_shim(): run ensure-shim.sh with SOURCE_SHIM/TARGET_SHIM --- lib.sh | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/lib.sh b/lib.sh index 442402e..81aed43 100644 --- a/lib.sh +++ b/lib.sh @@ -104,3 +104,59 @@ function find_cursor_appimage() { done return 1 } + +# --- Shim (cursor in PATH): canonical paths and helpers --- +# Requires LIB_DIR to be set by caller before sourcing lib. +REPO_OWNER="${REPO_OWNER:-watzon}" +REPO_BRANCH="${REPO_BRANCH:-main}" +REPO_NAME="${REPO_NAME:-cursor-linux-installer}" +BASE_RAW_URL="https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/${REPO_BRANCH}" +SHIM_TARGET="${SHIM_TARGET:-$HOME/.local/bin/cursor}" +SHARED_SHIM="${LIB_DIR}/shim.sh" +SHIM_HELPER="${LIB_DIR}/ensure-shim.sh" +SHIM_URL="${BASE_RAW_URL}/shim.sh" +SHIM_HELPER_URL="${BASE_RAW_URL}/scripts/ensure-shim.sh" +LIB_URL="${BASE_RAW_URL}/lib.sh" +CURSOR_SCRIPT_URL="${BASE_RAW_URL}/cursor.sh" + +# Sync shim.sh and ensure-shim.sh into LIB_DIR (local copy or download). +# Set LOCAL_SHIM_PATH and/or LOCAL_SHIM_HELPER_PATH to prefer repo files. +function sync_shim_assets() { + mkdir -p "$LIB_DIR" + if [ -n "${LOCAL_SHIM_PATH:-}" ] && [ -f "$LOCAL_SHIM_PATH" ]; then + cp "$LOCAL_SHIM_PATH" "$SHARED_SHIM" + elif [ ! -f "$SHARED_SHIM" ]; then + curl -fsSL "$SHIM_URL" -o "$SHARED_SHIM" || { log_warn "Failed to download shim.sh"; return 1; } + fi + if [ -n "${LOCAL_SHIM_HELPER_PATH:-}" ] && [ -f "$LOCAL_SHIM_HELPER_PATH" ]; then + cp "$LOCAL_SHIM_HELPER_PATH" "$SHIM_HELPER" + elif [ ! -f "$SHIM_HELPER" ]; then + curl -fsSL "$SHIM_HELPER_URL" -o "$SHIM_HELPER" || { log_warn "Failed to download ensure-shim.sh"; return 1; } + fi + chmod +x "$SHIM_HELPER" "$SHARED_SHIM" 2>/dev/null || true + return 0 +} + +# Refresh shim assets from GitHub (used on cursor-installer --update). +function refresh_shim_assets() { + log_step "Refreshing cursor shim assets..." + mkdir -p "$LIB_DIR" + if ! curl -fsSL "$SHIM_URL" -o "$SHARED_SHIM"; then + log_warn "Failed to download shim.sh; continuing." + return 0 + fi + if ! curl -fsSL "$SHIM_HELPER_URL" -o "$SHIM_HELPER"; then + log_warn "Failed to download ensure-shim.sh; continuing." + return 0 + fi + chmod +x "$SHIM_HELPER" "$SHARED_SHIM" 2>/dev/null || true +} + +# Run ensure-shim.sh with canonical SOURCE_SHIM and TARGET_SHIM. +function run_ensure_shim() { + if [ ! -x "$SHIM_HELPER" ] && [ ! -f "$SHIM_HELPER" ]; then + log_info "Shim helper not found; skipping shim update." + return 0 + fi + SOURCE_SHIM="$SHARED_SHIM" TARGET_SHIM="$SHIM_TARGET" "$SHIM_HELPER" || { log_warn "Shim update failed; continuing."; return 0; } +} From b8d7ea416b8fbe76687d882238016b67382845bd Mon Sep 17 00:00:00 2001 From: ZanzyTHEbar Date: Wed, 18 Feb 2026 12:11:30 +0000 Subject: [PATCH 3/5] refactor(install): use lib sync_shim_assets and run_ensure_shim - Replace inline shim sync block with LOCAL_SHIM_PATH/LOCAL_SHIM_HELPER_PATH env + sync_shim_assets && run_ensure_shim - Keep REPO_*, LIB_URL, CURSOR_SCRIPT_URL for bootstrap before first lib source --- install.sh | 50 ++++++-------------------------------------------- 1 file changed, 6 insertions(+), 44 deletions(-) diff --git a/install.sh b/install.sh index dc5b624..707b5d0 100755 --- a/install.sh +++ b/install.sh @@ -32,23 +32,15 @@ done # Determine whether to use local cursor.sh or download from GitHub SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) LOCAL_CURSOR_SH="$SCRIPT_DIR/cursor.sh" - -# Repo URL parameters (override via env for release workflows) +LIB_DIR="$HOME/.local/share/cursor-installer" +LIB_PATH="$SCRIPT_DIR/lib.sh" +SHARED_LIB="$LIB_DIR/lib.sh" REPO_OWNER=${REPO_OWNER:-watzon} REPO_BRANCH=${REPO_BRANCH:-main} REPO_NAME=${REPO_NAME:-cursor-linux-installer} BASE_RAW_URL="https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/${REPO_BRANCH}" -CURSOR_SCRIPT_URL="$BASE_RAW_URL/cursor.sh" -LIB_DIR="$HOME/.local/share/cursor-installer" -LIB_PATH="$SCRIPT_DIR/lib.sh" -SHARED_LIB="$LIB_DIR/lib.sh" -LIB_URL="$BASE_RAW_URL/lib.sh" -SHIM_PATH="$SCRIPT_DIR/shim.sh" -SHARED_SHIM="$LIB_DIR/shim.sh" -SHIM_URL="$BASE_RAW_URL/shim.sh" -SHIM_HELPER_LOCAL="$SCRIPT_DIR/scripts/ensure-shim.sh" -SHIM_HELPER="$LIB_DIR/ensure-shim.sh" -SHIM_HELPER_URL="$BASE_RAW_URL/scripts/ensure-shim.sh" +LIB_URL="${BASE_RAW_URL}/lib.sh" +CURSOR_SCRIPT_URL="${BASE_RAW_URL}/cursor.sh" # Source shared helpers (local repo, installed lib, or download) if [ -f "$LIB_PATH" ]; then @@ -103,37 +95,7 @@ chmod +x "$CLI_PATH" log_ok "Cursor installer script has been placed in $CLI_PATH" log_step "Ensuring cursor shim..." -SHIM_READY=true -if [ -f "$SHIM_PATH" ]; then - cp "$SHIM_PATH" "$SHARED_SHIM" -elif [ -f "$SHARED_SHIM" ]; then - : -else - log_info "Downloading shim.sh from GitHub..." - if ! curl -fsSL "$SHIM_URL" -o "$SHARED_SHIM"; then - log_warn "Failed to download shim.sh; shim update skipped." - SHIM_READY=false - fi -fi - -if [ "$SHIM_READY" = true ]; then - if [ -f "$SHIM_HELPER_LOCAL" ]; then - cp "$SHIM_HELPER_LOCAL" "$SHIM_HELPER" - else - log_info "Downloading ensure-shim.sh from GitHub..." - if ! curl -fsSL "$SHIM_HELPER_URL" -o "$SHIM_HELPER"; then - log_warn "Failed to download ensure-shim.sh; shim update skipped." - SHIM_READY=false - fi - fi -fi - -if [ "$SHIM_READY" = true ]; then - chmod +x "$SHIM_HELPER" "$SHARED_SHIM" || true - if ! "$SHIM_HELPER"; then - log_warn "Shim update failed; continuing installation." - fi -fi +LOCAL_SHIM_PATH="$SCRIPT_DIR/shim.sh" LOCAL_SHIM_HELPER_PATH="$SCRIPT_DIR/scripts/ensure-shim.sh" sync_shim_assets && run_ensure_shim || log_warn "Shim update skipped or failed; continuing." # Check if ~/.local/bin is in PATH if [[ ":$PATH:" != *":$LOCAL_BIN:"* ]]; then From 3ff581afd233fbdd06b022e21d8b8e420ce5ca11 Mon Sep 17 00:00:00 2001 From: ZanzyTHEbar Date: Wed, 18 Feb 2026 12:11:31 +0000 Subject: [PATCH 4/5] refactor(cursor): use lib shim helpers, remove duplicate logic - Drop local REPO_*, SHARED_SHIM, SHIM_*, ensure_shim, refresh_shim_assets - Call refresh_shim_assets in update_cursor, run_ensure_shim in install paths --- cursor.sh | 45 +++------------------------------------------ 1 file changed, 3 insertions(+), 42 deletions(-) diff --git a/cursor.sh b/cursor.sh index 5631e9a..3c7c12e 100755 --- a/cursor.sh +++ b/cursor.sh @@ -21,14 +21,6 @@ fi CLI_NAME="cursor-installer" CLI_BIN="$HOME/.local/bin/$CLI_NAME" -REPO_OWNER=${REPO_OWNER:-watzon} -REPO_BRANCH=${REPO_BRANCH:-main} -REPO_NAME=${REPO_NAME:-cursor-linux-installer} -BASE_RAW_URL="https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/${REPO_BRANCH}" -SHARED_SHIM="$LIB_DIR/shim.sh" -SHIM_URL="$BASE_RAW_URL/shim.sh" -SHIM_HELPER="$LIB_DIR/ensure-shim.sh" -SHIM_HELPER_URL="$BASE_RAW_URL/scripts/ensure-shim.sh" # Installation mode: 'appimage' (default) or 'extracted' # Can be set via CURSOR_INSTALL_MODE environment variable or --extract flag @@ -48,44 +40,13 @@ function get_extracted_root() { fi done return 1 -} +} function get_extraction_dir() { # Prefer ~/.local/share/cursor for extracted installations echo "$HOME/.local/share/cursor" } -function ensure_shim() { - if [ -x "$SHIM_HELPER" ]; then - if ! "$SHIM_HELPER"; then - log_warn "Shim update failed; continuing." - fi - return 0 - fi - if [ -f "$SHIM_HELPER" ]; then - if ! sh "$SHIM_HELPER"; then - log_warn "Shim update failed; continuing." - fi - return 0 - fi - log_info "Shim helper not found; skipping shim update." - return 0 -} - -function refresh_shim_assets() { - log_step "Refreshing cursor shim assets..." - mkdir -p "$LIB_DIR" - if ! curl -fsSL "$SHIM_URL" -o "$SHARED_SHIM"; then - log_warn "Failed to download shim.sh; continuing." - return 0 - fi - if ! curl -fsSL "$SHIM_HELPER_URL" -o "$SHIM_HELPER"; then - log_warn "Failed to download ensure-shim.sh; continuing." - return 0 - fi - chmod +x "$SHIM_HELPER" "$SHARED_SHIM" || true -} - function check_fuse() { # First, check if FUSE is already available if fusermount -V >/dev/null 2>&1; then @@ -328,7 +289,7 @@ EOF } function install_cursor_extracted() { - ensure_shim + run_ensure_shim local install_dir="$1" local release_track=${2:-stable} local temp_file @@ -478,7 +439,7 @@ function install_cursor_extracted() { } function install_cursor() { - ensure_shim + run_ensure_shim local install_dir="$1" local release_track=${2:-stable} # Default to stable if not specified From f4b5c3f738a5eef410c972499c8c56a6be50f20f Mon Sep 17 00:00:00 2001 From: ZanzyTHEbar Date: Fri, 20 Feb 2026 11:49:36 +0000 Subject: [PATCH 5/5] docs: add cursor shim documentation to README Explain what the shim is, why it exists, how it works, when it runs, file locations, and manual removal steps. --- README.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5181bb3..367d9fe 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,8 @@ The one‑liner script will: 1. Download the `cursor.sh` script and save it as `cursor-installer` in `~/.local/bin/` 2. Download `lib.sh` to `~/.local/share/cursor-installer/lib.sh` 3. Make the script executable -4. Download and install the latest version of Cursor +4. Install a `cursor` shim at `~/.local/bin/cursor` (see [The `cursor` Shim](#the-cursor-shim)) +5. Download and install the latest version of Cursor **Note:** If you're installing via the piped bash method and don't have FUSE2 installed, the script will warn you but continue. You'll need to either: @@ -126,6 +127,8 @@ The uninstall script will: 3. Remove the Cursor AppImage 4. Ask if you want to remove the Cursor configuration files +**Note:** The `cursor` shim at `~/.local/bin/cursor` is not removed by the uninstall script. See [Removing the Shim](#removing-the-shim) for manual cleanup. + ## Usage Note: The installer CLI is `cursor-installer` to avoid conflicts with Cursor's official `cursor` CLI. @@ -196,6 +199,69 @@ cursor-installer --update stable **Note:** The extracted installation is stored in `~/.local/share/cursor/`. +## The `cursor` Shim + +### Why + +Cursor now ships an official `cursor` CLI, but this project predates it. The installer CLI is named `cursor-installer` to avoid colliding with the official binary. On systems where Cursor was installed through this project alone, there may be no `cursor` command on PATH. + +The shim bridges that gap. It installs a lightweight script at `~/.local/bin/cursor` that transparently forwards to the real Cursor CLI when present, and falls back to `cursor-installer` when it isn't. + +### What It Does + +When you type `cursor`, the shim (`~/.local/bin/cursor`) follows a short resolution chain: + +1. **Real Cursor binary found in PATH?** -- Forward all arguments to it (e.g. Cursor's official `cursor` CLI). +2. **`cursor agent` subcommand?** -- Delegate to `~/.local/bin/agent` if it exists. +3. **`cursor-installer` found?** -- Delegate to the installer CLI so commands like `cursor --update` still work. +4. **Nothing found** -- Print a helpful error with install instructions. + +The shim never hides a real Cursor binary; it only acts as a fallback. + +### How It Works + +Two scripts cooperate: + +| File | Purpose | +| --- | --- | +| `shim.sh` | The shim itself, installed as `~/.local/bin/cursor`. | +| `scripts/ensure-shim.sh` | Idempotent installer/updater for the shim. | + +**`ensure-shim.sh` safety guards:** + +- If `~/.local/bin/cursor` does not exist, the shim is installed. +- If it exists and is already the current shim (byte-identical), nothing happens. +- If it exists and _is_ a shim (detected by shebang + marker string), it is updated. +- If it exists and is _not_ a shim (e.g. a real Cursor binary, a symlink you created, etc.), **it is never overwritten**. + +### When It Runs + +The shim is synced automatically during normal installer operations: + +- **`install.sh`** -- Copies `shim.sh` and `ensure-shim.sh` into `~/.local/share/cursor-installer/`, then runs `ensure-shim.sh`. +- **`cursor-installer --update`** -- Re-downloads the latest shim assets from GitHub, then re-runs `ensure-shim.sh`. +- **`cursor-installer` (install paths)** -- Runs `ensure-shim.sh` before each install to keep the shim current. + +### File Locations + +| Path | Description | +| --- | --- | +| `~/.local/bin/cursor` | The shim (what you invoke). | +| `~/.local/share/cursor-installer/shim.sh` | Cached copy of the shim source. | +| `~/.local/share/cursor-installer/ensure-shim.sh` | Cached copy of the installer helper. | + +### Removing the Shim + +The uninstall script does not currently remove the shim. To remove it manually: + +```bash +rm ~/.local/bin/cursor +rm -f ~/.local/share/cursor-installer/shim.sh +rm -f ~/.local/share/cursor-installer/ensure-shim.sh +``` + +If you only want to disable the shim without uninstalling the rest of the project, removing `~/.local/bin/cursor` is sufficient. + ## Note If you encounter a warning that `~/.local/bin` is not in your PATH, you can add it by running: