-
Notifications
You must be signed in to change notification settings - Fork 19
feat: cursor shim for ~/.local/bin/cursor #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
321dabc
dd6e4bc
b8d7ea4
3ff581a
f4b5c3f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The PATH probe only excludes the literal string Useful? React with 👍 / 👎.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would the shim be invoked from anywhere else? This seems like a non-existent edgecase.
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just Codex doing Codex things haha. It does like to be thorough.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey! So after looking at this, I took some time to stress test my local setup and I WAS able to hit this edge-case. I will provide a fix for it. How I did it:
This caused the shim to re-discover itself as the shim only used raw string comparison. I was then faced with a terminal "hang" as the shim re-executed itself. |
||
| 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 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cursorThe non-shim protection is too broad: any executable shell script containing the text
cursor-installeris treated as an existing shim and eligible for overwrite. That means user-managed wrappers at~/.local/bin/cursorcan be silently replaced even when they are not this project's shim, which contradicts the safety guarantee in this change.Useful? React with 👍 / 👎.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This, also, seems like an edge-case that does not practically exist. When would a user ever have another cursor-installer on PATH?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fair honestly