Skip to content

Update Fleet-maintained apps - #50651

Merged
allenhouchins merged 1 commit into
mainfrom
fma-2608060017
Aug 6, 2026
Merged

Update Fleet-maintained apps#50651
allenhouchins merged 1 commit into
mainfrom
fma-2608060017

Conversation

@fleet-release

@fleet-release fleet-release commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Automated ingestion of latest Fleet-maintained app data.

Summary by CodeRabbit

  • New Features
    • Added the latest available releases for a broad range of macOS and Windows applications, including Signal, AWS VPN Client, WebStorm, Zed, Filebeat, Loom, Ollama, and others.
    • Updated installer details and verification checks to support reliable installation of current versions.
  • Bug Fixes
    • Improved removal behavior for selected applications, including cleanup of background services, cached data, recent documents, and related components.
    • Updated uninstall handling for applications with changed installer identifiers.

Generated automatically with cmd/maintained-apps.
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/apparency/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/archaeology/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/aws-cli/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/aws-vpn-client/darwin.json

=== Install Script (no changes) ===
=== Uninstall // 695f03a0 -> 66fca039 ===

--- /tmp/old.kUC58l	2026-08-06 00:26:24.781596972 +0000
+++ /tmp/new.dPQnKO	2026-08-06 00:26:24.782596992 +0000
@@ -229,13 +229,16 @@
 }
 
 remove_launchctl_service 'com.amazonaws.acvc.helper'
+remove_launchctl_service 'com.amazonaws.acvc.osx.core'
 quit_application 'com.amazonaws.acvc.osx'
 remove_pkg_files 'com.amazon.awsvpnclient'
 forget_pkg 'com.amazon.awsvpnclient'
 sudo rm -rf '/Applications/AWS VPN Client'
 sudo rm -rf '/Library/Application Support/AWSVPNClient'
 sudo rm -rf '/Library/LaunchDaemons/com.amazonaws.acvc.helper.plist'
+sudo rm -rf '/Library/LaunchDaemons/com.amazonaws.acvc.osx.core.plist'
 sudo rm -rf '/Library/PrivilegedHelperTools/com.amazonaws.acvc.helper'
+sudo rm -rf '/usr/local/bin/aws-vpn-client'
 trash $LOGGED_IN_USER '~/.config/AWSVPNClient'
 trash $LOGGED_IN_USER '~/Library/Preferences/com.amazonaws.acvc.osx.plist'
 trash $LOGGED_IN_USER '~/Library/Saved Application State/com.amazonaws.acvc.osx.savedState'

ee/maintained-apps/outputs/bitwig-studio/windows.json

=== Install Script (no changes) ===
=== Uninstall // 9b9fc2cf -> 1a228845 ===

--- /tmp/old.0JXSvL	2026-08-06 00:26:24.849598309 +0000
+++ /tmp/new.2XThNl	2026-08-06 00:26:24.849598309 +0000
@@ -1,4 +1,4 @@
-$product_code = '{8AFA291D-C7A6-4461-9A6A-A5B38120BAF0}'
+$product_code = '{4D03AFE3-5239-449A-A3D9-C070BF04F350}'
 $timeoutSeconds = 300  # 5 minute timeout
 
 # Fleet uninstalls app using product code that's extracted on upload

ee/maintained-apps/outputs/brave-browser/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/clion/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/companion/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/cyberduck/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/dataflare/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/egnyte/darwin.json

=== Install Script (no changes) ===
=== Uninstall // 34c8aecc -> 5de28e16 ===

--- /tmp/old.MyXYLT	2026-08-06 00:26:25.075602751 +0000
+++ /tmp/new.IHdEoE	2026-08-06 00:26:25.076602771 +0000
@@ -5,6 +5,76 @@
 LOGGED_IN_USER=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')
 # functions
 
+remove_launchctl_service() {
+  local service="$1"
+  local booleans=("true" "false")
+  local plist_status
+  local paths
+  local should_sudo
+
+  echo "Removing launchctl service ${service}"
+
+  # A wildcard label can't be used with launchctl or as a plist name, so expand
+  # it to the labels of currently loaded services that match the pattern.
+  local services=("$service")
+  if [[ "$service" == *"*"* ]]; then
+    local regex
+    # Escape regex metacharacters, turn '*' into '.*', and anchor the pattern so
+    # it matches a full label rather than a substring.
+    regex=$(printf '%s' "$service" | sed -e 's/[][(){}.^$+?|\\]/\\&/g' -e 's/\*/.*/g')
+    regex="^${regex}$"
+    services=()
+    local id
+    # Match every loaded job by label regardless of PID; launchctl list reports
+    # loaded-but-not-running jobs with a "-" in the PID column.
+    while read -r _ _ id; do
+      [[ "$id" =~ $regex ]] && services+=("$id")
+    done < <(launchctl list 2>/dev/null | tail -n +2)
+    if [[ ${#services[@]} -eq 0 ]]; then
+      echo "No loaded launchctl service matches ${service}"
+      return
+    fi
+  fi
+
+  local service_label
+  for service_label in "${services[@]}"; do
+    for should_sudo in "${booleans[@]}"; do
+      plist_status=$(launchctl list "${service_label}" 2>/dev/null)
+
+      if [[ $plist_status == \{* ]]; then
+        if [[ $should_sudo == "true" ]]; then
+          sudo launchctl remove "${service_label}"
+        else
+          launchctl remove "${service_label}"
+        fi
+        sleep 1
+      fi
+
+      paths=(
+        "/Library/LaunchAgents/${service_label}.plist"
+        "/Library/LaunchDaemons/${service_label}.plist"
+      )
+
+      # if not using sudo, prepend the home directory to the paths
+      if [[ $should_sudo == "false" ]]; then
+        for i in "${!paths[@]}"; do
+          paths[i]="${HOME}${paths[i]}"
+        done
+      fi
+
+      for path in "${paths[@]}"; do
+        if [[ -e "$path" ]]; then
+          if [[ $should_sudo == "true" ]]; then
+            sudo rm -f -- "$path"
+          else
+            rm -f -- "$path"
+          fi
+        fi
+      done
+    done
+  done
+}
+
 trash() {
   local logged_in_user="$1"
   local target_file="$2"
@@ -52,13 +122,18 @@
   fi
 }
 
+remove_launchctl_service 'com.egnyte.DesktopLaunchHelper'
+remove_launchctl_service 'FELUD555VC.group.com.egnyte.DesktopApp.XPCBroker'
 sudo rm -rf "$APPDIR/Egnyte.app"
 trash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopApp'
 trash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopApp.FileProvider'
 trash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopApp.FinderHelper'
 trash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopApp.FinderHelper.FinderSync'
+trash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopLaunchHelper'
 trash $LOGGED_IN_USER '~/Library/Application Scripts/FELUD555VC.group.com.egnyte.DesktopApp'
 trash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.egnyte.desktopapp.sfl*'
+trash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.egnyte.desktoplaunchhelper.sfl*'
+trash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/felud555vc.group.com.egnyte.desktopapp.xpcbroker.sfl*'
 trash $LOGGED_IN_USER '~/Library/Application Support/FileProvider/com.egnyte.DesktopApp.FileProvider'
 trash $LOGGED_IN_USER '~/Library/Caches/SentryCrash/EgnyteLaunchHelper'
 trash $LOGGED_IN_USER '~/Library/Caches/SentryCrash/EgnyteUpgradeChecker'
@@ -67,5 +142,7 @@
 trash $LOGGED_IN_USER '~/Library/Containers/com.egnyte.DesktopApp.FileProvider'
 trash $LOGGED_IN_USER '~/Library/Containers/com.egnyte.DesktopApp.FinderHelper'
 trash $LOGGED_IN_USER '~/Library/Containers/com.egnyte.DesktopApp.FinderHelper.FinderSync'
+trash $LOGGED_IN_USER '~/Library/Containers/com.egnyte.DesktopLaunchHelper'
+trash $LOGGED_IN_USER '~/Library/Containers/FELUD555VC.group.com.egnyte.DesktopApp.XPCBroker'
 trash $LOGGED_IN_USER '~/Library/Group Containers/FELUD555VC.group.com.egnyte.DesktopApp'
 trash $LOGGED_IN_USER '~/Library/Preferences/com.apple.FileProvider/com.egnyte.DesktopApp.FileProvider'

ee/maintained-apps/outputs/filebeat/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/firefox@developer-edition/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/gitkraken/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/google-drive/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/grammarly-desktop/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/heidisql/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/hive-app/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/loom/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/loom/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/macpacker/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/megasync/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/microsoft-office/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/nodejs/windows.json

=== Install Script (no changes) ===
=== Uninstall // fe1dc93a -> db9a38f0 ===

--- /tmp/old.mWW8Me	2026-08-06 00:26:25.594612953 +0000
+++ /tmp/new.XYwI10	2026-08-06 00:26:25.594612953 +0000
@@ -1,4 +1,4 @@
-$product_code = '{09051536-C2FF-4E63-B5ED-F98A6D700260}'
+$product_code = '{7308A298-0F07-41A9-B373-72E1FAA64CBB}'
 $timeoutSeconds = 300  # 5 minute timeout
 
 # Fleet uninstalls app using product code that's extracted on upload

ee/maintained-apps/outputs/ollama/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/ollama/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/opencode-desktop/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/pdf-expert/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/postman/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/proton-mail/darwin.json

=== Install Script (no changes) ===
=== Uninstall // 8e5ef0af -> a5eb828a ===

--- /tmp/old.bgTBFy	2026-08-06 00:26:25.829617573 +0000
+++ /tmp/new.uGHz2b	2026-08-06 00:26:25.829617573 +0000
@@ -52,7 +52,9 @@
   fi
 }
 
+sudo rm -rf '/Applications/Proton Mail Uninstaller.app'
 sudo rm -rf "$APPDIR/Proton Mail.app"
+trash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/ch.protonmail.desktop.sfl*'
 trash $LOGGED_IN_USER '~/Library/Application Support/Proton Mail'
 trash $LOGGED_IN_USER '~/Library/Caches/ch.protonmail.desktop'
 trash $LOGGED_IN_USER '~/Library/Caches/ch.protonmail.desktop.ShipIt'

ee/maintained-apps/outputs/pycharm/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/remote-desktop-manager/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/scribe/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/signal/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/signal/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/spotify/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/superhuman/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/suspicious-package/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/tailscale/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/telegram/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/textexpander/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/webstorm/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/webstorm/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/winlogbeat/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/zed/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/zed/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Updated maintained app manifests with newer versions, patch queries, installer URLs, and SHA-256 checksums. The changes cover macOS and Windows applications. AWS VPN Client, Bitwig Studio, Egnyte, Node.js, and Proton Mail also update uninstall references or cleanup behavior.

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is on topic but omits the required issue reference, checklist status, and testing information. Complete the template sections, or remove non-applicable items and document the testing performed for the automated update.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: updating Fleet-maintained app data.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fma-2608060017

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 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/egnyte/darwin.json`:
- Line 20: Add a bounded application-quit step before bundle removal: in
ee/maintained-apps/outputs/egnyte/darwin.json at lines 20-20, quit
com.egnyte.DesktopApp before rm -rf "$APPDIR/Egnyte.app"; in
ee/maintained-apps/outputs/proton-mail/darwin.json at lines 20-20, quit
ch.protonmail.desktop before rm -rf "$APPDIR/Proton Mail.app". Validate both
uninstall flows while their applications are open, ensuring the quit operation
cannot block indefinitely.

In `@ee/maintained-apps/outputs/gitkraken/darwin.json`:
- Line 9: Make both generic macOS manifests architecture-aware: in
ee/maintained-apps/outputs/gitkraken/darwin.json at lines 9-9, add the matching
Intel/universal artifact or restrict the manifest to arm64; apply the same
choice in ee/maintained-apps/outputs/aws-vpn-client/darwin.json at lines 9-9 by
adding the x86_64 artifact or restricting support to arm64. Ensure each manifest
cannot select an ARM64-only installer for Intel macOS.

In `@ee/maintained-apps/outputs/nodejs/windows.json`:
- Around line 4-20: Update the Node.js Windows metadata to use an available
official release, such as v26.5.1, instead of v26.7.0. Regenerate the version,
patched query, installer_url, sha256, and the uninstall script’s MSI product
code together from that release, while keeping the existing install and
uninstall behavior unchanged.
🪄 Autofix

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 Plus

Run ID: f9433e0e-9636-4afc-89fd-a448e76a2b1a

📥 Commits

Reviewing files that changed from the base of the PR and between 8c6bedf and d90d2d9.

📒 Files selected for processing (46)
  • ee/maintained-apps/outputs/apparency/darwin.json
  • ee/maintained-apps/outputs/archaeology/darwin.json
  • ee/maintained-apps/outputs/aws-cli/windows.json
  • ee/maintained-apps/outputs/aws-vpn-client/darwin.json
  • ee/maintained-apps/outputs/bitwig-studio/windows.json
  • ee/maintained-apps/outputs/brave-browser/darwin.json
  • ee/maintained-apps/outputs/clion/darwin.json
  • ee/maintained-apps/outputs/companion/darwin.json
  • ee/maintained-apps/outputs/cyberduck/windows.json
  • ee/maintained-apps/outputs/dataflare/windows.json
  • ee/maintained-apps/outputs/egnyte/darwin.json
  • ee/maintained-apps/outputs/filebeat/windows.json
  • ee/maintained-apps/outputs/firefox@developer-edition/darwin.json
  • ee/maintained-apps/outputs/gitkraken/darwin.json
  • ee/maintained-apps/outputs/google-drive/windows.json
  • ee/maintained-apps/outputs/grammarly-desktop/darwin.json
  • ee/maintained-apps/outputs/heidisql/windows.json
  • ee/maintained-apps/outputs/hive-app/darwin.json
  • ee/maintained-apps/outputs/loom/darwin.json
  • ee/maintained-apps/outputs/loom/windows.json
  • ee/maintained-apps/outputs/macpacker/darwin.json
  • ee/maintained-apps/outputs/megasync/windows.json
  • ee/maintained-apps/outputs/microsoft-office/windows.json
  • ee/maintained-apps/outputs/nodejs/windows.json
  • ee/maintained-apps/outputs/ollama/darwin.json
  • ee/maintained-apps/outputs/ollama/windows.json
  • ee/maintained-apps/outputs/opencode-desktop/darwin.json
  • ee/maintained-apps/outputs/pdf-expert/darwin.json
  • ee/maintained-apps/outputs/postman/windows.json
  • ee/maintained-apps/outputs/proton-mail/darwin.json
  • ee/maintained-apps/outputs/pycharm/windows.json
  • ee/maintained-apps/outputs/remote-desktop-manager/windows.json
  • ee/maintained-apps/outputs/scribe/windows.json
  • ee/maintained-apps/outputs/signal/darwin.json
  • ee/maintained-apps/outputs/signal/windows.json
  • ee/maintained-apps/outputs/spotify/windows.json
  • ee/maintained-apps/outputs/superhuman/darwin.json
  • ee/maintained-apps/outputs/suspicious-package/darwin.json
  • ee/maintained-apps/outputs/tailscale/windows.json
  • ee/maintained-apps/outputs/telegram/windows.json
  • ee/maintained-apps/outputs/textexpander/windows.json
  • ee/maintained-apps/outputs/webstorm/darwin.json
  • ee/maintained-apps/outputs/webstorm/windows.json
  • ee/maintained-apps/outputs/winlogbeat/windows.json
  • ee/maintained-apps/outputs/zed/darwin.json
  • ee/maintained-apps/outputs/zed/windows.json

"34c8aecc": "#!/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/Egnyte.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopApp'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopApp.FileProvider'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopApp.FinderHelper'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopApp.FinderHelper.FinderSync'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/FELUD555VC.group.com.egnyte.DesktopApp'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.egnyte.desktopapp.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/FileProvider/com.egnyte.DesktopApp.FileProvider'\ntrash $LOGGED_IN_USER '~/Library/Caches/SentryCrash/EgnyteLaunchHelper'\ntrash $LOGGED_IN_USER '~/Library/Caches/SentryCrash/EgnyteUpgradeChecker'\ntrash $LOGGED_IN_USER '~/Library/CloudStorage/Egnyte-*'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.egnyte.DesktopApp'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.egnyte.DesktopApp.FileProvider'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.egnyte.DesktopApp.FinderHelper'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.egnyte.DesktopApp.FinderHelper.FinderSync'\ntrash $LOGGED_IN_USER '~/Library/Group Containers/FELUD555VC.group.com.egnyte.DesktopApp'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.apple.FileProvider/com.egnyte.DesktopApp.FileProvider'\n",
"5495db25": "#!/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 'com.egnyte.DesktopApp'\nif [ -d \"$APPDIR/Egnyte.app\" ]; then\n\tsudo mv \"$APPDIR/Egnyte.app\" \"$TMPDIR/Egnyte.app.bkp\" || exit $?\nfi\nif ! sudo cp -R \"$TMPDIR/Egnyte.app\" \"$APPDIR\"; then\n\t# remove the partial copy so a failed install isn't inventoried as the new\n\t# version, then restore the previous version if there was one\n\tsudo rm -rf \"$APPDIR/Egnyte.app\"\n\tif [ -d \"$TMPDIR/Egnyte.app.bkp\" ]; then\n\t\tsudo mv \"$TMPDIR/Egnyte.app.bkp\" \"$APPDIR/Egnyte.app\"\n\tfi\n\texit 1\nfi\nrelaunch_application 'com.egnyte.DesktopApp'\n"
"5495db25": "#!/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 'com.egnyte.DesktopApp'\nif [ -d \"$APPDIR/Egnyte.app\" ]; then\n\tsudo mv \"$APPDIR/Egnyte.app\" \"$TMPDIR/Egnyte.app.bkp\" || exit $?\nfi\nif ! sudo cp -R \"$TMPDIR/Egnyte.app\" \"$APPDIR\"; then\n\t# remove the partial copy so a failed install isn't inventoried as the new\n\t# version, then restore the previous version if there was one\n\tsudo rm -rf \"$APPDIR/Egnyte.app\"\n\tif [ -d \"$TMPDIR/Egnyte.app.bkp\" ]; then\n\t\tsudo mv \"$TMPDIR/Egnyte.app.bkp\" \"$APPDIR/Egnyte.app\"\n\tfi\n\texit 1\nfi\nrelaunch_application 'com.egnyte.DesktopApp'\n",
"5de28e16": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nremove_launchctl_service() {\n local service=\"$1\"\n local booleans=(\"true\" \"false\")\n local plist_status\n local paths\n local should_sudo\n\n echo \"Removing launchctl service ${service}\"\n\n # A wildcard label can't be used with launchctl or as a plist name, so expand\n # it to the labels of currently loaded services that match the pattern.\n local services=(\"$service\")\n if [[ \"$service\" == *\"*\"* ]]; then\n local regex\n # Escape regex metacharacters, turn '*' into '.*', and anchor the pattern so\n # it matches a full label rather than a substring.\n regex=$(printf '%s' \"$service\" | sed -e 's/[][(){}.^$+?|\\\\]/\\\\&/g' -e 's/\\*/.*/g')\n regex=\"^${regex}$\"\n services=()\n local id\n # Match every loaded job by label regardless of PID; launchctl list reports\n # loaded-but-not-running jobs with a \"-\" in the PID column.\n while read -r _ _ id; do\n [[ \"$id\" =~ $regex ]] && services+=(\"$id\")\n done < <(launchctl list 2>/dev/null | tail -n +2)\n if [[ ${#services[@]} -eq 0 ]]; then\n echo \"No loaded launchctl service matches ${service}\"\n return\n fi\n fi\n\n local service_label\n for service_label in \"${services[@]}\"; do\n for should_sudo in \"${booleans[@]}\"; do\n plist_status=$(launchctl list \"${service_label}\" 2>/dev/null)\n\n if [[ $plist_status == \\{* ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo launchctl remove \"${service_label}\"\n else\n launchctl remove \"${service_label}\"\n fi\n sleep 1\n fi\n\n paths=(\n \"/Library/LaunchAgents/${service_label}.plist\"\n \"/Library/LaunchDaemons/${service_label}.plist\"\n )\n\n # if not using sudo, prepend the home directory to the paths\n if [[ $should_sudo == \"false\" ]]; then\n for i in \"${!paths[@]}\"; do\n paths[i]=\"${HOME}${paths[i]}\"\n done\n fi\n\n for path in \"${paths[@]}\"; do\n if [[ -e \"$path\" ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo rm -f -- \"$path\"\n else\n rm -f -- \"$path\"\n fi\n fi\n done\n done\n done\n}\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\nremove_launchctl_service 'com.egnyte.DesktopLaunchHelper'\nremove_launchctl_service 'FELUD555VC.group.com.egnyte.DesktopApp.XPCBroker'\nsudo rm -rf \"$APPDIR/Egnyte.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopApp'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopApp.FileProvider'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopApp.FinderHelper'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopApp.FinderHelper.FinderSync'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.egnyte.DesktopLaunchHelper'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/FELUD555VC.group.com.egnyte.DesktopApp'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.egnyte.desktopapp.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.egnyte.desktoplaunchhelper.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/felud555vc.group.com.egnyte.desktopapp.xpcbroker.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/FileProvider/com.egnyte.DesktopApp.FileProvider'\ntrash $LOGGED_IN_USER '~/Library/Caches/SentryCrash/EgnyteLaunchHelper'\ntrash $LOGGED_IN_USER '~/Library/Caches/SentryCrash/EgnyteUpgradeChecker'\ntrash $LOGGED_IN_USER '~/Library/CloudStorage/Egnyte-*'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.egnyte.DesktopApp'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.egnyte.DesktopApp.FileProvider'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.egnyte.DesktopApp.FinderHelper'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.egnyte.DesktopApp.FinderHelper.FinderSync'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.egnyte.DesktopLaunchHelper'\ntrash $LOGGED_IN_USER '~/Library/Containers/FELUD555VC.group.com.egnyte.DesktopApp.XPCBroker'\ntrash $LOGGED_IN_USER '~/Library/Group Containers/FELUD555VC.group.com.egnyte.DesktopApp'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.apple.FileProvider/com.egnyte.DesktopApp.FileProvider'\n"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Repository files matching darwin.json:"
git ls-files 'ee/maintained-apps/outputs/*/darwin.json' | sort | sed -n '1,200p'

echo
echo "Relevant script snippets:"
for f in ee/maintained-apps/outputs/egnyte/darwin.json ee/maintained-apps/outputs/proton-mail/darwin.json; do
  echo "--- $f"
  sed -n '1,26p' "$f"
  echo "Kill/quit/app references:"
  rg -n "kill|pkill|terminate|quit|com\.egnyte|Egnyte|proton|Proton|rm -rf|rm -r|Egnyte\.app|Proton Mail" "$f" || true
done

echo
echo "Search for maintenance/uninstall acceptance flow reference in repository:"
rg -n "uninstall|maintained-app|acceptance|open|while open|fleetdm/fleet/issues/18865|18865" . --glob '!**/node_modules/**' --glob '!**/.git/**' | sed -n '1,240p'

Repository: fleetdm/fleet

Length of output: 50369


🌐 Web query:

Fleet maintained apps uninstall acceptance flow issue 18865

💡 Result:

Issue 18865 refers to a major project within the Fleet device management platform focused on implementing "Fleet-maintained apps" for macOS [1][2]. This feature provides a curated library of applications that Fleet tests for successful installation and uninstallation to ensure reliability for administrators [1]. Regarding issues with the uninstall flow for these apps, the topic has been subject to ongoing development and troubleshooting: 1. False Positives: There have been reports where Fleet-maintained apps fail to uninstall correctly but still display a "successful" message in the user interface (a false positive) [3]. This has been observed with specific software like Cloudflare WARP and Box Drive [3]. Troubleshooting indicated that these issues often arise from nuances in how specific apps handle uninstallation—such as lack of directives to quit open apps or complications with custom uninstaller scripts—which require app-specific handling [3]. 2. Scope and Updates: Issue 18865 serves as a parent tracker for this initiative [4]. Related sub-tasks and separate issues have addressed specific bugs, such as improving error handling [5], managing different file formats (e.g.,.dmg and.zip) [4], and addressing failures in default uninstaller scripts for other formats like MSI [6]. 3. Differentiation from VPP: It is important to distinguish these issues from App Store (VPP) apps. Separate efforts (such as issue 20729 and 25077) were required to add support for uninstalling and revoking licenses for VPP-managed apps, as those were initially limited or lacked native uninstall functionality within Fleet [7][8][9]. If you are experiencing a specific failure, it is recommended to check the Fleet GitHub repository for the latest bug reports, as the platform team has been actively addressing uninstall logic, error reporting, and app-specific requirements [5][10][3].

Citations:


Quit each app before uninstall cleanup.

These uninstall scripts remove active app bundles without quitting them first. Add a bounded quit step before deleting Egnyte.app and Proton Mail.app, and validate uninstall while the application is open.

  • ee/maintained-apps/outputs/egnyte/darwin.json#L5de28e16: quit com.egnyte.DesktopApp before rm -rf "$APPDIR/Egnyte.app".
  • ee/maintained-apps/outputs/proton-mail/darwin.json#La5eb828a: quit ch.protonmail.desktop before rm -rf "$APPDIR/Proton Mail.app".
📍 Affects 2 files
  • ee/maintained-apps/outputs/egnyte/darwin.json#L20-L20 (this comment)
  • ee/maintained-apps/outputs/proton-mail/darwin.json#L20-L20
🤖 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/egnyte/darwin.json` at line 20, Add a bounded
application-quit step before bundle removal: in
ee/maintained-apps/outputs/egnyte/darwin.json at lines 20-20, quit
com.egnyte.DesktopApp before rm -rf "$APPDIR/Egnyte.app"; in
ee/maintained-apps/outputs/proton-mail/darwin.json at lines 20-20, quit
ch.protonmail.desktop before rm -rf "$APPDIR/Proton Mail.app". Validate both
uninstall flows while their applications are open, ensuring the quit operation
cannot block indefinitely.

Source: MCP tools

"patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.axosoft.gitkraken' AND version_compare(bundle_short_version, '12.4.0') < 0);"
},
"installer_url": "https://api.gitkraken.dev/releases/production/darwin/arm64/12.3.1/GitKraken-v12.3.1.zip",
"installer_url": "https://api.gitkraken.dev/releases/production/darwin/arm64/12.4.0/GitKraken-v12.4.0.zip",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Tracked files around maintained-apps outputs:"
git ls-files 'ee/maintained-apps/outputs/**' | sed -n '1,120p'

echo
echo "GitKraken darwin.json:"
cat -n ee/maintained-apps/outputs/gitkraken/darwin.json

echo
echo "AWS VPN Client darwin.json:"
cat -n ee/maintained-apps/outputs/aws-vpn-client/darwin.json

echo
echo "Schema-ish files:"
find ee/maintained-apps -maxdepth 3 -type f \( -name '*.json' -o -name '*.yml' -o -name '*.yaml' -o -name '*.schema.json' \) | sed -n '1,200p'

echo
echo "Search for architecture/selectors in maintained apps:"
rg -n '"architecture"|"architectures"|"architecture_selector"|darwin|installer_url|unqualified|output|maintained-apps' ee/maintained-apps -S --glob '!**/.git/**' | sed -n '1,240p'

Repository: fleetdm/fleet

Length of output: 50369


🌐 Web query:

GitKraken 12.4.0 macOS installer universal Intel vs Apple Silicon support documentation

💡 Result:

GitKraken Desktop for macOS does not use a single universal binary; instead, it provides separate, architecture-specific builds for Intel-based Macs and Apple Silicon Macs [1][2]. Official documentation and support guidance explicitly require users to download the build that matches their specific Mac chipset [1][2]. Installing the incorrect build—such as running the Intel version on an Apple Silicon machine—is technically possible but not recommended, as it often leads to performance issues, including increased CPU and GPU usage, higher power consumption, and louder fan activity due to the overhead of the emulation layer [1][2][3]. For GitKraken Desktop 12.4.0, users should verify their architecture and select the corresponding installer from the official GitKraken download page [4][5]. If you have installed the wrong version, you can verify your current build by navigating to the GitKraken menu within the application, and if a mismatch is detected, you should download and install the correct version for your specific processor [2].

Citations:


🌐 Web query:

AWS Client VPN Client macOS Amazon Client VPN download macOS Intel Apple Silicon

💡 Result:

You can download the official AWS Client VPN for macOS directly from the Amazon Web Services website [1][2]. The software is available for both Intel (x86_64) and Apple Silicon (ARM64) architectures [1][3]. To download the latest version: 1. Visit the official AWS Client VPN Download page at https://aws.amazon.com/vpn/client-vpn-download/ [1][2]. 2. Locate the section for macOS and choose the appropriate installer for your system: - macOS (ARM64) for Apple Silicon Macs [1][3]. - macOS (x64) for Intel-based Macs [1][3]. Alternatively, if your organization has set up a Client VPN self-service portal, you may be able to download the client and your configuration files directly from that portal [4][5]. The portal can be accessed at https://self-service.clientvpn.amazonaws.com/ by entering your Client VPN endpoint ID [6][7][4]. The AWS-provided client for macOS supports macOS versions including Sonoma (14.0), Sequoia (15.0), and Tahoe (26.0) [2][8]. Note that the AWS-provided client does not support automatic updates, so you should check the official release notes periodically for new versions [2][3]. For endpoints using SAML-based federated authentication, use of the AWS-provided client is required, particularly on Apple Silicon (ARM) architectures [9].

Citations:


Make ARM64-only macOS artifacts architecture-aware.

Both generic darwin manifests select architecture-specific ARM64 installers, and existing GitKraken downloads support separate macOS Intel and Apple Silicon builds. Select the matching artifact for each architecture, or restrict these entries to Apple Silicon only.

  • ee/maintained-apps/outputs/gitkraken/darwin.json#L9: add an Intel/universal GitKraken artifact or narrow support to arm64.
  • ee/maintained-apps/outputs/aws-vpn-client/darwin.json#L9: add the macOS x86_64 AWS Client VPN artifact or narrow support to arm64.
📍 Affects 2 files
  • ee/maintained-apps/outputs/gitkraken/darwin.json#L9-L9 (this comment)
  • ee/maintained-apps/outputs/aws-vpn-client/darwin.json#L9-L9
🤖 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/gitkraken/darwin.json` at line 9, Make both
generic macOS manifests architecture-aware: in
ee/maintained-apps/outputs/gitkraken/darwin.json at lines 9-9, add the matching
Intel/universal artifact or restrict the manifest to arm64; apply the same
choice in ee/maintained-apps/outputs/aws-vpn-client/darwin.json at lines 9-9 by
adding the x86_64 artifact or restricting support to arm64. Ensure each manifest
cannot select an ARM64-only installer for Intel macOS.

Source: MCP tools

Comment on lines +4 to +20
"version": "26.7.0",
"queries": {
"exists": "SELECT 1 FROM programs WHERE name = 'Node.js' AND publisher = 'Node.js Foundation';",
"patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Node.js' AND publisher = 'Node.js Foundation' AND version_compare(version, '26.5.1') < 0);"
"patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = 'Node.js' AND publisher = 'Node.js Foundation' AND version_compare(version, '26.7.0') < 0);"
},
"installer_url": "https://nodejs.org/dist/v26.5.1/node-v26.5.1-x64.msi",
"installer_url": "https://nodejs.org/dist/v26.7.0/node-v26.7.0-x64.msi",
"install_script_ref": "22e48c46",
"uninstall_script_ref": "fe1dc93a",
"sha256": "826a4551bb9d3c00c61c17a2521a1e901ac7304e3090a3c2d07c1e0fe2b4d60d",
"uninstall_script_ref": "db9a38f0",
"sha256": "28dd9d5e53f829a32310a4fed334000a1681a7534641c599d05617f893c06a2b",
"default_categories": [
"Developer tools"
]
}
],
"refs": {
"22e48c46": "$logFile = \"${env:TEMP}/fleet-install-software.log\"\n\n# MSI exit codes that indicate success. 3010 = ERROR_SUCCESS_REBOOT_REQUIRED,\n# 1641 = ERROR_SUCCESS_REBOOT_INITIATED. Treat these as success rather than failure.\n$successCodes = @(0, 3010, 1641)\n\ntry {\n\n$installProcess = Start-Process msiexec.exe `\n -ArgumentList \"/quiet /norestart /lv `\"${logFile}`\" /i `\"${env:INSTALLER_PATH}`\"\" `\n -PassThru -Verb RunAs -Wait\n\nGet-Content $logFile -Tail 500\n\nif ($successCodes -contains $installProcess.ExitCode) {\n Exit 0\n}\n\nExit $installProcess.ExitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n",
"fe1dc93a": "$product_code = '{09051536-C2FF-4E63-B5ED-F98A6D700260}'\n$timeoutSeconds = 300 # 5 minute timeout\n\n# Fleet uninstalls app using product code that's extracted on upload\n$process = Start-Process msiexec -ArgumentList @(\"/quiet\", \"/x\", $product_code, \"/norestart\") -PassThru\n\n# Wait for process with timeout\n$completed = $process.WaitForExit($timeoutSeconds * 1000)\n\nif (-not $completed) {\n Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue\n Exit 1603 # ERROR_UNINSTALL_FAILURE\n}\n\n# MSI exit codes that indicate success. 3010 = ERROR_SUCCESS_REBOOT_REQUIRED,\n# 1641 = ERROR_SUCCESS_REBOOT_INITIATED. Treat these as success rather than failure.\n$successCodes = @(0, 3010, 1641)\n\n# Check exit code and output result\nif ($successCodes -contains $process.ExitCode) {\n Write-Output \"Exit 0\"\n Exit 0\n} else {\n Write-Output \"Exit $($process.ExitCode)\"\n Exit $process.ExitCode\n}\n"
"db9a38f0": "$product_code = '{7308A298-0F07-41A9-B373-72E1FAA64CBB}'\n$timeoutSeconds = 300 # 5 minute timeout\n\n# Fleet uninstalls app using product code that's extracted on upload\n$process = Start-Process msiexec -ArgumentList @(\"/quiet\", \"/x\", $product_code, \"/norestart\") -PassThru\n\n# Wait for process with timeout\n$completed = $process.WaitForExit($timeoutSeconds * 1000)\n\nif (-not $completed) {\n Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue\n Exit 1603 # ERROR_UNINSTALL_FAILURE\n}\n\n# MSI exit codes that indicate success. 3010 = ERROR_SUCCESS_REBOOT_REQUIRED,\n# 1641 = ERROR_SUCCESS_REBOOT_INITIATED. Treat these as success rather than failure.\n$successCodes = @(0, 3010, 1641)\n\n# Check exit code and output result\nif ($successCodes -contains $process.ExitCode) {\n Write-Output \"Exit 0\"\n Exit 0\n} else {\n Write-Output \"Exit $($process.ExitCode)\"\n Exit $process.ExitCode\n}\n"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Replace the unavailable Node.js release metadata.

At review time on August 6, 2026, node-v26.7.0-x64.msi returns 404, while Node's official release index exposes v26.5.1. This prevents installation before checksum verification or uninstallation. Select an existing vendor release, then regenerate the version, patch query, installer URL, checksum, and MSI product code together. ()

🤖 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/nodejs/windows.json` around lines 4 - 20, Update
the Node.js Windows metadata to use an available official release, such as
v26.5.1, instead of v26.7.0. Regenerate the version, patched query,
installer_url, sha256, and the uninstall script’s MSI product code together from
that release, while keeping the existing install and uninstall behavior
unchanged.

Source: MCP tools

@allenhouchins
allenhouchins merged commit cfe2a08 into main Aug 6, 2026
18 checks passed
@allenhouchins
allenhouchins deleted the fma-2608060017 branch August 6, 2026 02:25
allenhouchins added a commit that referenced this pull request Aug 6, 2026
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** NA — follow-up to #49910

## What changed

Regenerates `api/fleet-desktop.json` and
`outputs/fleet-desktop/darwin.json` for Fleet Desktop v1.4.0. No cask
changes.

## Why

#49910 bumped `Casks/fleet-desktop.rb` to 1.4.0 but never ran
`regenerate.sh` or the ingester, so the generated manifests — the files
Fleet actually serves — were still on 1.3.4 and still pointed at the old
`allenhouchins/fleet-desktop` GitHub release URL. That release feed is
stale (it stops at v1.3.4); 1.4.0 is hosted at `download.fleetdm.com`.
The `.rb` bump had no effect in production, and nothing in CI catches
this kind of drift.

This was found during a routine custom-tap maintenance pass. All four
casks (druva-insync, fleet-desktop, xcreds, zoom-rooms) are at their
latest upstream versions, so this is the only change needed:

| Cask | Version | Upstream | |
|---|---|---|---|
| druva-insync | 8.1.3,110967 | `inSync-8.1.3r110967` | current |
| fleet-desktop | 1.4.0 | 1.4.0 (1.4.1 → 404) | **manifests were stale**
|
| xcreds | 5.9,9148 | `tag-5.9(9148)` | current |
| zoom-rooms | 7.1.5.13403 | `cdn.zoom.us/prod/7.1.5.13403/` | current |

## Notes for reviewers

Verified the 1.4.0 installer against the cask stanzas before
regenerating:

- sha256 of the downloaded pkg matches the cask's `c920b983…`
- receipt id `com.fleetdm.fleet-desktop` (from `PackageInfo`) matches
both the `pkgutil:` and `quit:` stanzas
- `CFBundleShortVersionString` is `1.4.0`, matching the cask version —
so the `patched` query won't produce a perpetual false "Update
available"
- the `pkg` stanza filename `fleet_desktop-v1.4.0.pkg` matches the
downloaded filename

`regenerate.sh` rebuilds all four api JSONs; only fleet-desktop changed,
so there was no brew schema drift to absorb on the others. The
`install_script_ref` changes (`5d021f75` → `0341b271`) only because the
pkg filename inside the script changed; `uninstall_script_ref` is
unchanged.

Unrelated, not addressed here: brew emits a deprecation warning on three
casks for `depends_on macos: ">= :ventura"` (string comparison) vs
`depends_on macos: :ventura`. It doesn't affect the generated JSON.

# Checklist for submitter

- [x] QA'd all new/changed functionality manually

## fleetd/orbit/Fleet Desktop

- [x] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes

This is a macOS-only FMA manifest regeneration — no Go code, no schema,
no fleetd/orbit runtime changes. The remaining template sections
(changes file, SQL/input validation, timeouts, automated tests,
migrations, config settings, fleetd compatibility/auto-update) don't
apply; prior custom-tap bumps (#49563, #50651) likewise carry no changes
file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants