@@ -11,37 +11,44 @@ function check_fuse() {
1111 cmd_prefix=" sudo"
1212 fi
1313
14- # Check and install FUSE using the appropriate package manager
14+ # FIXED: Check and install FUSE2 using the appropriate package manager
1515 if command -v apt-get & > /dev/null; then
16- if ! dpkg -l | grep -q " ^ii.*fuse " ; then
17- echo " Installing FUSE ..."
16+ if ! dpkg -l | grep -q " ^ii.*libfuse2 " ; then # FIXED: libfuse2, not fuse
17+ echo " Installing libfuse2 ..."
1818 $cmd_prefix apt-get update
19- $cmd_prefix apt-get install -y fuse
19+ $cmd_prefix apt-get install -y libfuse2 # FIXED: libfuse2 for AppImage compat
2020 else
21- echo " FUSE is already installed."
21+ echo " libfuse2 is already installed."
2222 fi
2323 elif command -v dnf & > /dev/null; then
2424 if ! rpm -q fuse > /dev/null 2>&1 ; then
25- echo " Installing FUSE ..."
25+ echo " Installing fuse ..."
2626 $cmd_prefix dnf install -y fuse
2727 else
28- echo " FUSE is already installed."
28+ echo " fuse is already installed."
2929 fi
3030 elif command -v pacman & > /dev/null; then
3131 if ! pacman -Qi fuse2 > /dev/null 2>&1 ; then
32- echo " Installing FUSE ..."
32+ echo " Installing fuse2 ..."
3333 $cmd_prefix pacman -S fuse2
3434 else
35- echo " FUSE is already installed."
35+ echo " fuse2 is already installed."
3636 fi
3737 else
38- echo " Unsupported package manager. Please install FUSE manually."
39- echo " You can install FUSE using your system's package manager:"
40- echo " - Debian/Ubuntu: ${cmd_prefix} apt-get install fuse "
38+ echo " Unsupported package manager. Please install libfuse2 manually."
39+ echo " You can install FUSE2 using your system's package manager:"
40+ echo " - Debian/Ubuntu: ${cmd_prefix} apt-get install libfuse2 " # FIXED: libfuse2
4141 echo " - Fedora: ${cmd_prefix} dnf install fuse"
4242 echo " - Arch Linux: ${cmd_prefix} pacman -S fuse2"
4343 exit 1
4444 fi
45+
46+ # Verify FUSE2 is functional
47+ if ! fusermount -V > /dev/null 2>&1 ; then
48+ echo " Warning: FUSE2 verification failed. AppImage may not run." >&2
49+ return 1
50+ fi
51+ echo " FUSE2 is ready."
4552}
4653
4754function get_arch() {
@@ -82,45 +89,53 @@ function get_install_dir() {
8289
8390function get_fallback_download_info() {
8491 local arch=$( get_arch)
85-
86- # this AppImage is potentially older than expected, see
87- # https://github.com/watzon/cursor-linux-installer/issues/5
88- echo " MESSAGE=$1 "
89- echo " URL=https://downloader.cursor.sh/linux/appImage/$arch "
90- echo " VERSION=fallback"
91- return 1
92+ local path_arch=" $arch " # NEW: x64/arm64 for path
93+ local file_arch=" x86_64" # NEW: Map for filename
94+ if [ " $arch " = " arm64" ]; then
95+ file_arch=" aarch64"
96+ fi
97+ local fallback_hash=" 8ea935e79a50a02da912a034bbeda84a6d3d355d" # FIXED: Recent from 0.50.4 (May 2025)
98+ local fallback_version=" 0.50.4" # FIXED: Updated version
99+ echo " URL=https://downloads.cursor.com/production/$fallback_hash /linux/$path_arch /Cursor-$fallback_version -$file_arch .AppImage"
100+ echo " VERSION=$fallback_version "
101+ return 1 # Still error, but usable URL
92102}
93103
94104function get_download_info() {
95- if ! which jq > /dev/null 2>&1 ; then
96- get_fallback_download_info " jq not available"
97- return 1
98- fi
99-
100- local temp_file=$( mktemp)
105+ local temp_html=$( mktemp)
101106 local release_track=${1:- stable} # Default to stable if not specified
102- local api_url=" https://www.cursor.com/api/download?platform=linux-$( get_arch) &releaseTrack=$release_track "
103-
104- echo " Fetching download info for $release_track track..."
105- if ! curl -sL " $api_url " -o " $temp_file " ; then
106- rm -f " $temp_file "
107- get_fallback_download_info " curl failed on $api_url "
108- return 1
107+ local arch=$( get_arch) # x64 or arm64
108+ local path_arch=" $arch " # NEW: For platform param (x64/arm64)
109+ local file_arch=" x86_64" # NEW: For filename filter (x86_64/aarch64)
110+ if [ " $arch " = " arm64" ]; then
111+ file_arch=" aarch64"
109112 fi
113+ local platform=" linux-${path_arch} "
114+ local api_url=" https://cursor.com/api/download?platform=$platform &releaseTrack=$release_track "
110115
111- if ! download_url=$( jq -er ' .downloadUrl' " $temp_file " ) ; then
112- rm -f " $temp_file "
113- get_fallback_download_info " jq failed: downloadUrl not found in JSON response"
116+ echo " Fetching download info for $release_track track ($file_arch )..."
117+ if ! curl -sL " $api_url " -o " $temp_html " ; then
118+ rm -f " $temp_html "
119+ get_fallback_download_info
114120 return 1
115121 fi
116122
117- if ! version=$( jq -er ' .version' " $temp_file " ) ; then
118- rm -f " $temp_file "
119- get_fallback_download_info " jq failed: version not found in JSON response"
123+ # FIXED: Arch-specific scrape (filters to correct binary)
124+ local download_url=$( grep -o " https://downloads\.cursor\.com/[^[:space:]]*${file_arch} \.AppImage" " $temp_html " | head -1 | sed ' s/["' \' ' ]\?$//' )
125+
126+ rm -f " $temp_html "
127+
128+ if [ -z " $download_url " ]; then
129+ get_fallback_download_info
120130 return 1
121131 fi
122132
123- rm -f " $temp_file "
133+ # Extract version from filename (e.g., Cursor-1.6.35-x86_64.AppImage → 1.6.35)
134+ local version=$( basename " $download_url " | sed -E ' s/.*Cursor-([0-9]+\.[0-9]+\.[0-9]+).*/\1/' )
135+
136+ if [ -z " $version " ]; then
137+ version=" unknown" # Rare fallback
138+ fi
124139
125140 echo " URL=$download_url "
126141 echo " VERSION=$version "
@@ -132,6 +147,7 @@ function install_cursor() {
132147 local release_track=${2:- stable} # Default to stable if not specified
133148 local temp_file=$( mktemp)
134149 local current_dir=$( pwd)
150+ local arch=$( get_arch) # NEW: For verification
135151 local download_info=$( get_download_info " $release_track " )
136152 local message=$( echo " $download_info " | grep " MESSAGE=" | sed ' s/^MESSAGE=//' )
137153
@@ -141,7 +157,7 @@ function install_cursor() {
141157 fi
142158
143159 # Check for FUSE before proceeding with installation
144- check_fuse
160+ check_fuse || return 1 # NEW: Propagate FUSE error
145161
146162 local download_url=$( echo " $download_info " | grep " URL=" | sed ' s/^URL=//' )
147163 local version=$( echo " $download_info " | grep " VERSION=" | sed ' s/^VERSION=//' )
@@ -156,6 +172,28 @@ function install_cursor() {
156172 chmod +x " $temp_file "
157173 mv " $temp_file " " $install_dir /cursor.appimage"
158174
175+ # Ensure execution permissions persist post-move (robust against FS quirks)
176+ chmod +x " $install_dir /cursor.appimage"
177+ if [ -x " $install_dir /cursor.appimage" ]; then
178+ echo " Execution permissions confirmed for $install_dir /cursor.appimage"
179+ else
180+ echo " Warning: Failed to set execution permissions—check filesystem." >&2
181+ return 1
182+ fi
183+
184+ # NEW: Verify binary architecture matches host
185+ local binary_info=$( file " $install_dir /cursor.appimage" 2> /dev/null || echo " unreadable" )
186+ local expected_grep=" x86-64"
187+ if [ " $arch " = " arm64" ]; then
188+ expected_grep=" ARM aarch64"
189+ fi
190+ if ! echo " $binary_info " | grep -q " $expected_grep " ; then
191+ echo " Error: Arch mismatch detected ($binary_info ). Expected $expected_grep . Aborting install." >&2
192+ rm -f " $install_dir /cursor.appimage"
193+ return 1
194+ fi
195+ echo " Binary verified: $binary_info "
196+
159197 # Store version information in a simple file
160198 echo " $version " > " $install_dir /.cursor_version"
161199
@@ -164,25 +202,46 @@ function install_cursor() {
164202 cd " $temp_extract_dir "
165203
166204 # Extract icons
167- " $install_dir /cursor.appimage" --appimage-extract " usr/share/icons" > /dev/null 2>&1
205+ if ! " $install_dir /cursor.appimage" --appimage-extract " usr/share/icons" > /dev/null 2>&1 ; then
206+ echo " Warning: Icon extraction failed—skipping." >&2
207+ fi
168208 # Extract desktop file
169- " $install_dir /cursor.appimage" --appimage-extract " cursor.desktop" > /dev/null 2>&1
209+ if ! " $install_dir /cursor.appimage" --appimage-extract " cursor.desktop" > /dev/null 2>&1 ; then
210+ echo " Warning: Desktop extraction failed—skipping." >&2
211+ fi
212+
213+ # NEW: Verify extraction succeeded before copying
214+ if [ ! -d " squashfs-root" ]; then
215+ echo " Error: Extraction failed (squashfs-root missing). Check arch/FUSE." >&2
216+ cd " $current_dir "
217+ rm -rf " $temp_extract_dir "
218+ return 1
219+ fi
170220
171221 # Copy icons
172222 local icon_dir=" $HOME /.local/share/icons/hicolor"
173223 mkdir -p " $icon_dir "
174- cp -r squashfs-root/usr/share/icons/hicolor/* " $icon_dir /"
224+ if [ -d " squashfs-root/usr/share/icons/hicolor" ]; then
225+ cp -r squashfs-root/usr/share/icons/hicolor/* " $icon_dir /" 2> /dev/null || echo " Warning: Icon copy failed."
226+ fi
175227
176228 # Copy desktop file
177229 local apps_dir=" $HOME /.local/share/applications"
178230 mkdir -p " $apps_dir "
179- cp squashfs-root/cursor.desktop " $apps_dir /"
231+ if [ -f " squashfs-root/cursor.desktop" ]; then
232+ cp squashfs-root/cursor.desktop " $apps_dir /"
233+ # Update desktop file to point to the correct AppImage location
234+ sed -i " s|Exec=.*|Exec=$install_dir /cursor.appimage --no-sandbox|g" " $apps_dir /cursor.desktop"
180235
181- # Update desktop file to point to the correct AppImage location
182- sed -i " s|Exec=.*|Exec= $install_dir / cursor.appimage --no-sandbox|g " " $apps_dir /cursor.desktop"
236+ # Fix potential icon name mismatch in the extracted desktop file
237+ sed -i ' s/^Icon=co.anysphere.cursor/Icon= cursor/ ' " $apps_dir /cursor.desktop"
183238
184- # Fix potential icon name mismatch in the extracted desktop file
185- sed -i ' s/^Icon=co.anysphere.cursor/Icon=cursor/' " $apps_dir /cursor.desktop"
239+ # NEW: Refresh desktop database for menu visibility
240+ update-desktop-database " $apps_dir " 2> /dev/null || true
241+ echo " .desktop file installed and updated."
242+ else
243+ echo " Warning: cursor.desktop not found in extraction—manual setup needed."
244+ fi
186245
187246 # Clean up
188247 cd " $current_dir "
@@ -194,7 +253,6 @@ function install_cursor() {
194253
195254function update_cursor() {
196255 echo " Updating Cursor..."
197- local arch=$( get_arch)
198256 local current_appimage=$( find_cursor_appimage)
199257 local install_dir
200258 local release_track=${1:- stable} # Default to stable if not specified
@@ -217,6 +275,17 @@ function launch_cursor() {
217275 cursor_appimage=$( find_cursor_appimage)
218276 fi
219277
278+ # NEW: Pre-launch safeguard (re-chmod + arch check)
279+ if [ ! -x " $cursor_appimage " ]; then
280+ echo " Fixing execution permissions..."
281+ chmod +x " $cursor_appimage "
282+ fi
283+ local binary_info=$( file " $cursor_appimage " 2> /dev/null || echo " unreadable" )
284+ if ! echo " $binary_info " | grep -q " $( get_arch | sed ' s/x64/x86-64/;s/arm64/ARM aarch64/' ) " ; then # Simplified arch map
285+ echo " Error: Arch mismatch in binary ($binary_info ). Re-update." >&2
286+ return 1
287+ fi
288+
220289 # Create a log file to capture output and errors
221290 local log_file=" /tmp/cursor_appimage.log"
222291
0 commit comments