Add VirtualBuddy as a macOS FMA - #46734
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #46734 +/- ##
==========================================
- Coverage 66.91% 66.91% -0.01%
==========================================
Files 2832 2833 +1
Lines 224970 224972 +2
Branches 11663 11524 -139
==========================================
+ Hits 150531 150532 +1
- Misses 60783 60784 +1
Partials 13656 13656
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
WalkthroughThis PR adds VirtualBuddy, a macOS virtualization application, to Fleet's maintained apps system. It introduces Homebrew metadata defining VirtualBuddy's package identifiers and format, creates a macOS app definition with version 2.1 that includes SQL-based existence checks, DMG download URL, and embedded Bash scripts for installation (mounting, copying to Applications, relaunching) and uninstallation (removing app and related binaries from user Library). The app is registered in the system's catalog for macOS (darwin), and a new React icon component with embedded PNG artwork is created and wired into the frontend's icon registry for software display. Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@ee/maintained-apps/outputs/virtualbuddy/darwin.json`:
- Around line 19-20: The uninstall/install currently create/remove the "vctool"
symlink in the process CWD which is nondeterministic; change both the removal
(rm -rf 'vctool') and the symlink creation (ln ... "vctool") to use an absolute
path (e.g. /usr/local/bin/vctool or a BIN_PATH variable) so the link is always
managed in a known location, ensure the target directory exists (mkdir -p), and
use sudo when writing to a system bin directory so the same absolute path is
removed and created reliably.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: f1b5b5d8-f5f0-4370-9cf9-6a3835b04f30
⛔ Files ignored due to path filters (1)
website/assets/images/app-icon-virtualbuddy-60x60@2x.pngis excluded by!**/*.png
📒 Files selected for processing (5)
ee/maintained-apps/inputs/homebrew/virtualbuddy.jsonee/maintained-apps/outputs/apps.jsonee/maintained-apps/outputs/virtualbuddy/darwin.jsonfrontend/pages/SoftwarePage/components/icons/VirtualBuddy.tsxfrontend/pages/SoftwarePage/components/icons/index.ts
| "53e198e6": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/VirtualBuddy.app\"\nsudo rm -rf 'vctool'\ntrash $LOGGED_IN_USER '~/Library/Application Support/VirtualBuddy'\ntrash $LOGGED_IN_USER '~/Library/Caches/codes.rambo.VirtualBuddy'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/codes.rambo.VirtualBuddy'\ntrash $LOGGED_IN_USER '~/Library/Preferences/codes.rambo.VirtualBuddy.plist'\n", | ||
| "c7f4aec0": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'codes.rambo.VirtualBuddy'\nif [ -d \"$APPDIR/VirtualBuddy.app\" ]; then\n\tsudo mv \"$APPDIR/VirtualBuddy.app\" \"$TMPDIR/VirtualBuddy.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/VirtualBuddy.app\" \"$APPDIR\"\nrelaunch_application 'codes.rambo.VirtualBuddy'\nmkdir -p .\n/bin/ln -h -f -s -- \"$APPDIR/VirtualBuddy.app/Contents/MacOS/vctool\" \"vctool\"\n" |
There was a problem hiding this comment.
Use an absolute path for vctool symlink install/uninstall.
On Line 20, ln ... "vctool" creates the link in the process CWD; on Line 19, rm -rf 'vctool' removes from CWD too. This makes behavior nondeterministic across execution contexts and can leave the CLI link unmanaged.
Proposed fix
- mkdir -p .
- /bin/ln -h -f -s -- "$APPDIR/VirtualBuddy.app/Contents/MacOS/vctool" "vctool"
+ BIN_DIR="/usr/local/bin"
+ [[ -d "/opt/homebrew/bin" ]] && BIN_DIR="/opt/homebrew/bin"
+ sudo /bin/ln -h -f -s -- "$APPDIR/VirtualBuddy.app/Contents/MacOS/vctool" "$BIN_DIR/vctool"- sudo rm -rf 'vctool'
+ sudo rm -f "/usr/local/bin/vctool" "/opt/homebrew/bin/vctool"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@ee/maintained-apps/outputs/virtualbuddy/darwin.json` around lines 19 - 20,
The uninstall/install currently create/remove the "vctool" symlink in the
process CWD which is nondeterministic; change both the removal (rm -rf 'vctool')
and the symlink creation (ln ... "vctool") to use an absolute path (e.g.
/usr/local/bin/vctool or a BIN_PATH variable) so the link is always managed in a
known location, ensure the target directory exists (mkdir -p), and use sudo when
writing to a system bin directory so the same absolute path is removed and
created reliably.
Summary by CodeRabbit