Skip to content

Commit 7faf8e3

Browse files
committed
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
1 parent d03fff3 commit 7faf8e3

4 files changed

Lines changed: 200 additions & 0 deletions

File tree

cursor.sh

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ fi
2121

2222
CLI_NAME="cursor-installer"
2323
CLI_BIN="$HOME/.local/bin/$CLI_NAME"
24+
REPO_OWNER=${REPO_OWNER:-watzon}
25+
REPO_BRANCH=${REPO_BRANCH:-main}
26+
REPO_NAME=${REPO_NAME:-cursor-linux-installer}
27+
BASE_RAW_URL="https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/${REPO_BRANCH}"
28+
SHARED_SHIM="$LIB_DIR/shim.sh"
29+
SHIM_URL="$BASE_RAW_URL/shim.sh"
30+
SHIM_HELPER="$LIB_DIR/ensure-shim.sh"
31+
SHIM_HELPER_URL="$BASE_RAW_URL/scripts/ensure-shim.sh"
2432

2533
# Installation mode: 'appimage' (default) or 'extracted'
2634
# Can be set via CURSOR_INSTALL_MODE environment variable or --extract flag
@@ -47,6 +55,37 @@ function get_extraction_dir() {
4755
echo "$HOME/.local/share/cursor"
4856
}
4957

58+
function ensure_shim() {
59+
if [ -x "$SHIM_HELPER" ]; then
60+
if ! "$SHIM_HELPER"; then
61+
log_warn "Shim update failed; continuing."
62+
fi
63+
return 0
64+
fi
65+
if [ -f "$SHIM_HELPER" ]; then
66+
if ! sh "$SHIM_HELPER"; then
67+
log_warn "Shim update failed; continuing."
68+
fi
69+
return 0
70+
fi
71+
log_info "Shim helper not found; skipping shim update."
72+
return 0
73+
}
74+
75+
function refresh_shim_assets() {
76+
log_step "Refreshing cursor shim assets..."
77+
mkdir -p "$LIB_DIR"
78+
if ! curl -fsSL "$SHIM_URL" -o "$SHARED_SHIM"; then
79+
log_warn "Failed to download shim.sh; continuing."
80+
return 0
81+
fi
82+
if ! curl -fsSL "$SHIM_HELPER_URL" -o "$SHIM_HELPER"; then
83+
log_warn "Failed to download ensure-shim.sh; continuing."
84+
return 0
85+
fi
86+
chmod +x "$SHIM_HELPER" "$SHARED_SHIM" || true
87+
}
88+
5089
function check_fuse() {
5190
# First, check if FUSE is already available
5291
if fusermount -V >/dev/null 2>&1; then
@@ -289,6 +328,7 @@ EOF
289328
}
290329

291330
function install_cursor_extracted() {
331+
ensure_shim
292332
local install_dir="$1"
293333
local release_track=${2:-stable}
294334
local temp_file
@@ -438,6 +478,7 @@ function install_cursor_extracted() {
438478
}
439479

440480
function install_cursor() {
481+
ensure_shim
441482
local install_dir="$1"
442483
local release_track=${2:-stable} # Default to stable if not specified
443484

@@ -663,6 +704,7 @@ EOF
663704

664705
function update_cursor() {
665706
log_step "Updating Cursor..."
707+
refresh_shim_assets
666708
local current_appimage
667709
current_appimage=$(find_cursor_appimage || true)
668710
local install_dir

install.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ LIB_DIR="$HOME/.local/share/cursor-installer"
4343
LIB_PATH="$SCRIPT_DIR/lib.sh"
4444
SHARED_LIB="$LIB_DIR/lib.sh"
4545
LIB_URL="$BASE_RAW_URL/lib.sh"
46+
SHIM_PATH="$SCRIPT_DIR/shim.sh"
47+
SHARED_SHIM="$LIB_DIR/shim.sh"
48+
SHIM_URL="$BASE_RAW_URL/shim.sh"
49+
SHIM_HELPER_LOCAL="$SCRIPT_DIR/scripts/ensure-shim.sh"
50+
SHIM_HELPER="$LIB_DIR/ensure-shim.sh"
51+
SHIM_HELPER_URL="$BASE_RAW_URL/scripts/ensure-shim.sh"
4652

4753
# Source shared helpers (local repo, installed lib, or download)
4854
if [ -f "$LIB_PATH" ]; then
@@ -96,6 +102,39 @@ chmod +x "$CLI_PATH"
96102

97103
log_ok "Cursor installer script has been placed in $CLI_PATH"
98104

105+
log_step "Ensuring cursor shim..."
106+
SHIM_READY=true
107+
if [ -f "$SHIM_PATH" ]; then
108+
cp "$SHIM_PATH" "$SHARED_SHIM"
109+
elif [ -f "$SHARED_SHIM" ]; then
110+
:
111+
else
112+
log_info "Downloading shim.sh from GitHub..."
113+
if ! curl -fsSL "$SHIM_URL" -o "$SHARED_SHIM"; then
114+
log_warn "Failed to download shim.sh; shim update skipped."
115+
SHIM_READY=false
116+
fi
117+
fi
118+
119+
if [ "$SHIM_READY" = true ]; then
120+
if [ -f "$SHIM_HELPER_LOCAL" ]; then
121+
cp "$SHIM_HELPER_LOCAL" "$SHIM_HELPER"
122+
else
123+
log_info "Downloading ensure-shim.sh from GitHub..."
124+
if ! curl -fsSL "$SHIM_HELPER_URL" -o "$SHIM_HELPER"; then
125+
log_warn "Failed to download ensure-shim.sh; shim update skipped."
126+
SHIM_READY=false
127+
fi
128+
fi
129+
fi
130+
131+
if [ "$SHIM_READY" = true ]; then
132+
chmod +x "$SHIM_HELPER" "$SHARED_SHIM" || true
133+
if ! "$SHIM_HELPER"; then
134+
log_warn "Shim update failed; continuing installation."
135+
fi
136+
fi
137+
99138
# Check if ~/.local/bin is in PATH
100139
if [[ ":$PATH:" != *":$LOCAL_BIN:"* ]]; then
101140
log_warn "$LOCAL_BIN is not in your PATH."

scripts/ensure-shim.sh

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/bin/sh
2+
# Install or update ~/.local/bin/cursor shim. Skips if existing file is already our shim.
3+
set -eu
4+
5+
TARGET_SHIM="${TARGET_SHIM:-$HOME/.local/bin/cursor}"
6+
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
7+
LIB_DIR="${HOME}/.local/share/cursor-installer"
8+
9+
SOURCE_SHIM="${SOURCE_SHIM:-}"
10+
if [ -z "$SOURCE_SHIM" ]; then
11+
if [ -f "$LIB_DIR/shim.sh" ]; then
12+
SOURCE_SHIM="$LIB_DIR/shim.sh"
13+
elif [ -f "$SCRIPT_DIR/shim.sh" ]; then
14+
SOURCE_SHIM="$SCRIPT_DIR/shim.sh"
15+
elif [ -f "$SCRIPT_DIR/../shim.sh" ]; then
16+
SOURCE_SHIM="$SCRIPT_DIR/../shim.sh"
17+
fi
18+
fi
19+
20+
if [ -z "$SOURCE_SHIM" ] || [ ! -f "$SOURCE_SHIM" ]; then
21+
echo "Error: shim.sh source not found." >&2
22+
exit 1
23+
fi
24+
25+
is_shim() {
26+
file="$1"
27+
[ -f "$file" ] || return 1
28+
first_line=$(head -n 1 "$file" 2>/dev/null || true)
29+
case "$first_line" in
30+
"#!/bin/sh"|\
31+
"#!/usr/bin/env sh"|\
32+
"#!/bin/bash"|\
33+
"#!/usr/bin/env bash")
34+
;;
35+
*)
36+
return 1
37+
;;
38+
esac
39+
if grep -q "Find cursor executable in PATH" "$file" 2>/dev/null; then
40+
return 0
41+
fi
42+
if grep -q "cursor-installer" "$file" 2>/dev/null; then
43+
return 0
44+
fi
45+
return 1
46+
}
47+
48+
is_current_shim() {
49+
is_shim "$TARGET_SHIM" || return 1
50+
cmp -s "$SOURCE_SHIM" "$TARGET_SHIM"
51+
}
52+
53+
if is_current_shim; then
54+
echo "Cursor shim already installed; skipping."
55+
exit 0
56+
fi
57+
58+
if [ ! -e "$TARGET_SHIM" ]; then
59+
mkdir -p "$(dirname "$TARGET_SHIM")"
60+
cp "$SOURCE_SHIM" "$TARGET_SHIM"
61+
chmod +x "$TARGET_SHIM"
62+
echo "Installed cursor shim at $TARGET_SHIM"
63+
exit 0
64+
fi
65+
66+
if ! is_shim "$TARGET_SHIM"; then
67+
echo "Skipping shim update; existing cursor is not a shim: $TARGET_SHIM"
68+
exit 0
69+
fi
70+
71+
cp "$SOURCE_SHIM" "$TARGET_SHIM"
72+
chmod +x "$TARGET_SHIM"
73+
echo "Updated cursor shim at $TARGET_SHIM"

shim.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/bin/sh
2+
set -eu
3+
4+
# Find cursor executable in PATH, excluding the current shim
5+
find_cursor() {
6+
old_IFS="$IFS"
7+
IFS=:
8+
for dir in $PATH; do
9+
[ -n "$dir" ] || continue
10+
cursor_path="$dir/cursor"
11+
if [ "$cursor_path" != "$HOME/.local/bin/cursor" ] && [ -x "$cursor_path" ]; then
12+
IFS="$old_IFS"
13+
echo "$cursor_path"
14+
return 0
15+
fi
16+
done
17+
IFS="$old_IFS"
18+
return 1
19+
}
20+
21+
OTHER_CURSOR=$(find_cursor || true)
22+
CURSOR_INSTALLER=$(command -v cursor-installer 2>/dev/null || true)
23+
AGENT_BIN="$HOME/.local/bin/agent"
24+
25+
if [ -n "${OTHER_CURSOR:-}" ]; then
26+
exec "$OTHER_CURSOR" "$@"
27+
fi
28+
29+
first_arg="${1:-}"
30+
31+
if [ "$first_arg" = "agent" ]; then
32+
if [ -x "$AGENT_BIN" ]; then
33+
exec "$AGENT_BIN" "$@"
34+
fi
35+
echo "Error: Cursor agent not found at $AGENT_BIN" 1>&2
36+
exit 1
37+
fi
38+
39+
if [ -n "${CURSOR_INSTALLER:-}" ]; then
40+
exec "$CURSOR_INSTALLER" "$@"
41+
fi
42+
43+
echo "Error: No Cursor IDE installation found." 1>&2
44+
echo "Install/update with: cursor-installer --update [stable|latest]" 1>&2
45+
echo "Or, install Cursor at https://cursor.com/download" 1>&2
46+
exit 1

0 commit comments

Comments
 (0)