Update Fleet-maintained apps - #49813
Conversation
Generated automatically with cmd/maintained-apps.
Script Diff Resultsee/maintained-apps/outputs/advanced-installer/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/akiflow/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/amie/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/anytype/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/aptakube/windows.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-sam-cli/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/bettertouchtool/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/betterzip/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/beyond-compare/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/brave-browser/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/brave-browser/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/burp-suite/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cleanmymac/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/clop/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/comet/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cursor/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dataflare/darwin.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/datagrip/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/datagrip/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dockside/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/drawio/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/enpass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/fellow/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/fellow/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===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/firefox@nightly/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/firefox@nightly/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/google-ads-editor/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/google-gemini/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/granola/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/granola/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/groove-omnidialer/darwin.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/hwmonitor/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/kiro-cli/darwin.json=== Install Script (no changes) ===
=== Uninstall // 31b59062 -> ed98f0de ===
--- /tmp/old.36rILL 2026-07-23 12:36:02.250956493 +0000
+++ /tmp/new.3SSd3P 2026-07-23 12:36:02.250956493 +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,10 +122,14 @@
fi
}
+remove_launchctl_service 'com.amazon.codewhisperer.launcher'
sudo rm -rf "$APPDIR/Kiro CLI.app"
trash $LOGGED_IN_USER '~/.kiro'
trash $LOGGED_IN_USER '~/.local/bin/kiro-cli'
trash $LOGGED_IN_USER '~/.local/bin/kiro-cli-chat'
trash $LOGGED_IN_USER '~/Library/Application Support/kiro-cli'
+trash $LOGGED_IN_USER '~/Library/Caches/com.amazon.codewhisperer'
trash $LOGGED_IN_USER '~/Library/Caches/dev.kiro.cli'
+trash $LOGGED_IN_USER '~/Library/LaunchAgents/com.amazon.codewhisperer.launcher.plist'
trash $LOGGED_IN_USER '~/Library/Preferences/dev.kiro.cli.plist'
+trash $LOGGED_IN_USER '~/Library/WebKit/com.amazon.codewhisperer'ee/maintained-apps/outputs/kiro/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/kiro/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/lookaway/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/macwhisper/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/marsedit/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/melodics/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/microsoft-teams/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/microsoft-teams/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/mozilla-vpn/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/mozilla-vpn/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/naps2/darwin.json=== Install // 54ba1114 -> 27c40399 ===
--- /tmp/old.DGfJJ2 2026-07-23 12:36:02.839962252 +0000
+++ /tmp/new.6rsAJb 2026-07-23 12:36:02.840962261 +0000
@@ -96,5 +96,5 @@
# install pkg files
quit_and_track_application 'com.naps2.desktop'
-sudo installer -pkg "$TMPDIR/naps2-8.3.1-mac-arm64.pkg" -target /
+sudo installer -pkg "$TMPDIR/naps2-8.3.2-mac-arm64.pkg" -target /
relaunch_application 'com.naps2.desktop'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/naps2/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nosql-workbench/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nosql-workbench/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/notepadexe/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/obs/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/only-switch/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/onlyoffice/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/picview/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/popclip/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/powerphotos/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/powershell/windows.json=== Install Script (no changes) ===
=== Uninstall // 0995d374 -> 06cf76b8 ===
--- /tmp/old.i4zF0G 2026-07-23 12:36:03.393967669 +0000
+++ /tmp/new.mA6ziZ 2026-07-23 12:36:03.393967669 +0000
@@ -1,4 +1,4 @@
-$product_code = '{7B031DCF-BDCE-47D6-89B9-4C558D76E773}'
+$product_code = '{92D9A5DC-8C64-40D5-B1BC-98DB9C7FDB7F}'
$timeoutSeconds = 300 # 5 minute timeout
# Fleet uninstalls app using product code that's extracted on uploadee/maintained-apps/outputs/prisma-browser/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/pritunl/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/pritunl/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rider/darwin.json=== Install Script (no changes) ===
=== Uninstall // c52dae57 -> 22db20ac ===
--- /tmp/old.wgby1O 2026-07-23 12:36:03.573969429 +0000
+++ /tmp/new.PMjeOx 2026-07-23 12:36:03.573969429 +0000
@@ -54,9 +54,9 @@
sudo rm -rf "$APPDIR/Rider.app"
sudo rm -rf 'rider'
-trash $LOGGED_IN_USER '~/Library/Application Support/Rider2026.1'
-trash $LOGGED_IN_USER '~/Library/Caches/Rider2026.1'
-trash $LOGGED_IN_USER '~/Library/Logs/Rider2026.1'
+trash $LOGGED_IN_USER '~/Library/Application Support/Rider2026.2'
+trash $LOGGED_IN_USER '~/Library/Caches/Rider2026.2'
+trash $LOGGED_IN_USER '~/Library/Logs/Rider2026.2'
trash $LOGGED_IN_USER '~/Library/Preferences/jetbrains.rider.71e559ef.plist'
-trash $LOGGED_IN_USER '~/Library/Preferences/Rider2026.1'
+trash $LOGGED_IN_USER '~/Library/Preferences/Rider2026.2'
trash $LOGGED_IN_USER '~/Library/Saved Application State/com.jetbrains.rider.savedState'ee/maintained-apps/outputs/rive/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rustrover/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/setapp/darwin.json=== Install Script (no changes) ===
=== Uninstall // e23bd29d -> 9ef05eb6 ===
--- /tmp/old.CkIkGZ 2026-07-23 12:36:03.710970768 +0000
+++ /tmp/new.0tx7D5 2026-07-23 12:36:03.710970768 +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,10 +122,19 @@
fi
}
+remove_launchctl_service 'com.setapp.DesktopClient.SetappAgent'
+remove_launchctl_service 'com.setapp.DesktopClient.SetappAssistant'
+remove_launchctl_service 'com.setapp.DesktopClient.SetappLauncher'
+remove_launchctl_service 'com.setapp.DesktopClient.SetappUpdater'
sudo rm -rf "$APPDIR/Setapp.app"
trash $LOGGED_IN_USER '~/Library/Application Scripts/com.setapp.DesktopClient.SetappAgent.FinderSyncExt'
+trash $LOGGED_IN_USER '~/Library/Application Support/Setapp*'
trash $LOGGED_IN_USER '~/Library/Caches/com.setapp.DesktopClient'
trash $LOGGED_IN_USER '~/Library/Caches/com.setapp.DesktopClient.SetappAgent'
+trash $LOGGED_IN_USER '~/Library/Containers/com.setapp.DesktopClient.SetappAgent.FinderSyncExt'
+trash $LOGGED_IN_USER '~/Library/HTTPStorages/com.setapp.DesktopClient*'
+trash $LOGGED_IN_USER '~/Library/LaunchAgents/com.setapp.DesktopClient.*plist'
trash $LOGGED_IN_USER '~/Library/Logs/Setapp'
+trash $LOGGED_IN_USER '~/Library/Preferences/com.setapp.DesktopClient.plist'
trash $LOGGED_IN_USER '~/Library/Preferences/com.setapp.DesktopClient.SetappAgent.plist'
trash $LOGGED_IN_USER '~/Library/Saved Application State/com.setapp.DesktopClient.savedState'ee/maintained-apps/outputs/sidenotes/darwin.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/snagit/darwin.json=== Install Script (no changes) ===
=== Uninstall // b52ff2b2 -> 59bfdeae ===
--- /tmp/old.FRQxyP 2026-07-23 12:36:03.892972548 +0000
+++ /tmp/new.IfJAX2 2026-07-23 12:36:03.892972548 +0000
@@ -5,6 +5,46 @@
LOGGED_IN_USER=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')
# functions
+quit_application() {
+ local bundle_id="$1"
+ local timeout_duration=10
+
+ # check if the application is running
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Quitting application '$bundle_id'..."
+
+ # try to quit the application within the timeout period
+ local quit_success=false
+ SECONDS=0
+ while (( SECONDS < timeout_duration )); do
+ if osascript -e "tell application id \"$bundle_id\" to quit" >/dev/null 2>&1; then
+ if ! pgrep -f "$bundle_id" >/dev/null 2>&1; then
+ echo "Application '$bundle_id' quit successfully."
+ quit_success=true
+ break
+ fi
+ fi
+ sleep 1
+ done
+
+ if [[ "$quit_success" = false ]]; then
+ echo "Application '$bundle_id' did not quit."
+ fi
+}
+
+
trash() {
local logged_in_user="$1"
local target_file="$2"
@@ -52,9 +92,14 @@
fi
}
+quit_application 'com.TechSmith.Snagit'
sudo rm -rf "$APPDIR/Snagit.app"
+trash $LOGGED_IN_USER '~/Library/Application Scripts/7TQL462TU8.com.techsmith.snagit'
+trash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.techsmith.snagit.sfl*'
+trash $LOGGED_IN_USER '~/Library/Application Support/Snagit'
trash $LOGGED_IN_USER '~/Library/Caches/com.TechSmith.Snagit*'
trash $LOGGED_IN_USER '~/Library/Group Containers/*.com.techsmith.snagit'
+trash $LOGGED_IN_USER '~/Library/HTTPStorages/com.TechSmith.Snagit*'
trash $LOGGED_IN_USER '~/Library/Preferences/com.TechSmith.Snagit*.plist'
trash $LOGGED_IN_USER '~/Library/Preferences/com.techsmith.snagit.capturehelper*.plist'
trash $LOGGED_IN_USER '~/Library/Saved Application State/com.TechSmith.Snagit*.savedState'ee/maintained-apps/outputs/sourcetree/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/superwhisper/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/tabby/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/trezor-suite/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/typora/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/visual-studio-code/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/vivaldi/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/wechat/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/whatsapp/darwin.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/workflowy/darwin.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) === |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
WalkthroughUpdated numerous Darwin and Windows maintained-app manifests to newer releases, synchronizing version checks, installer URLs, and SHA-256 checksums. Updated lifecycle scripts for selected applications, including uninstall cleanup, DMG/PKG installation handling, and bounded Mozilla VPN MSI installation. Changed ONLYOFFICE’s installer format to DMG, added its Winget install script configuration, and marked the Typora Winget input as frozen. Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 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: 7
🤖 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/kiro-cli/darwin.json`:
- Line 20: Update remove_launchctl_service in both
ee/maintained-apps/outputs/kiro-cli/darwin.json and
ee/maintained-apps/outputs/setapp/darwin.json to resolve the logged-in console
user’s UID and remove /Library/LaunchAgents through that user’s launchctl domain
using launchctl asuser or bootout gui before deleting the plist; retain
system-domain handling for other entries.
In `@ee/maintained-apps/outputs/onlyoffice/darwin.json`:
- Around line 9-12: The OnlyOffice Darwin artifact format is inconsistent with
the referenced installation script. Update the configuration around
installer_url and install_script_ref so they use matching ZIP-based artifacts
and unzip logic, or switch to a DMG-compatible install script reference that
mounts and copies from the DMG; ensure sha256 matches the selected installer.
In `@ee/maintained-apps/outputs/rider/darwin.json`:
- Line 20: Update the Rider uninstall path handling to remove the documented
JetBrains directories under ~/Library: Application
Support/JetBrains/Rider2026.2, Caches/JetBrains/Rider2026.2, and
Logs/JetBrains/Rider2026.2. Replace the existing Rider2026.2 paths that omit the
JetBrains parent directory, and ensure all three data locations are deleted.
- Line 20: Update the Rider uninstall script in
ee/maintained-apps/outputs/rider/darwin.json at line 20 to invoke the bounded
quit_and_track_application() flow for com.jetbrains.rider before deleting or
moving Rider.app, preserving the existing relaunch tracking behavior as
applicable. Apply the same pre-cleanup quit pattern to the Setapp uninstall
script in ee/maintained-apps/outputs/setapp/darwin.json at line 20 if its
uninstall path removes a running application bundle.
- Line 20: The uninstall flow must terminate Rider before removing its
application bundle. Reuse the existing bounded quit logic from
quit_and_track_application, or invoke that shared helper, immediately before
sudo rm -rf "$APPDIR/Rider.app"; preserve the timeout behavior and ensure
removal proceeds only after the quit attempt.
In `@ee/maintained-apps/outputs/trezor-suite/darwin.json`:
- Around line 4-9: Update the installer_url for the Trezor Suite 26.7.2 manifest
to use the immutable versioned release directory instead of latest, preserving
the existing filename and checksum alignment; confirm the versioned URL path
exists before applying the change.
In `@ee/maintained-apps/outputs/zed/darwin.json`:
- Line 9: Update the installer_url in darwin.json to use a universal Zed macOS
artifact or the appropriate architecture-specific package selection, ensuring
both Apple Silicon and Intel clients receive compatible installers instead of
only Zed-aarch64.dmg.
🪄 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 Plus
Run ID: ce645285-1de7-4e54-a640-eb6d73bc0ed5
📒 Files selected for processing (87)
ee/maintained-apps/outputs/advanced-installer/windows.jsonee/maintained-apps/outputs/akiflow/darwin.jsonee/maintained-apps/outputs/amie/darwin.jsonee/maintained-apps/outputs/anytype/darwin.jsonee/maintained-apps/outputs/aptakube/windows.jsonee/maintained-apps/outputs/aws-cli/windows.jsonee/maintained-apps/outputs/aws-sam-cli/windows.jsonee/maintained-apps/outputs/bettertouchtool/darwin.jsonee/maintained-apps/outputs/betterzip/darwin.jsonee/maintained-apps/outputs/beyond-compare/darwin.jsonee/maintained-apps/outputs/brave-browser/darwin.jsonee/maintained-apps/outputs/brave-browser/windows.jsonee/maintained-apps/outputs/burp-suite/darwin.jsonee/maintained-apps/outputs/cleanmymac/darwin.jsonee/maintained-apps/outputs/clop/darwin.jsonee/maintained-apps/outputs/comet/windows.jsonee/maintained-apps/outputs/cursor/darwin.jsonee/maintained-apps/outputs/dataflare/darwin.jsonee/maintained-apps/outputs/dataflare/windows.jsonee/maintained-apps/outputs/datagrip/darwin.jsonee/maintained-apps/outputs/datagrip/windows.jsonee/maintained-apps/outputs/dockside/darwin.jsonee/maintained-apps/outputs/drawio/windows.jsonee/maintained-apps/outputs/enpass/windows.jsonee/maintained-apps/outputs/fellow/darwin.jsonee/maintained-apps/outputs/fellow/windows.jsonee/maintained-apps/outputs/filebeat/windows.jsonee/maintained-apps/outputs/firefox@developer-edition/darwin.jsonee/maintained-apps/outputs/firefox@nightly/darwin.jsonee/maintained-apps/outputs/firefox@nightly/windows.jsonee/maintained-apps/outputs/google-ads-editor/windows.jsonee/maintained-apps/outputs/google-gemini/darwin.jsonee/maintained-apps/outputs/granola/darwin.jsonee/maintained-apps/outputs/granola/windows.jsonee/maintained-apps/outputs/groove-omnidialer/darwin.jsonee/maintained-apps/outputs/hive-app/darwin.jsonee/maintained-apps/outputs/hwmonitor/windows.jsonee/maintained-apps/outputs/kiro-cli/darwin.jsonee/maintained-apps/outputs/kiro/darwin.jsonee/maintained-apps/outputs/kiro/windows.jsonee/maintained-apps/outputs/lookaway/darwin.jsonee/maintained-apps/outputs/loom/darwin.jsonee/maintained-apps/outputs/loom/windows.jsonee/maintained-apps/outputs/macwhisper/darwin.jsonee/maintained-apps/outputs/marsedit/darwin.jsonee/maintained-apps/outputs/megasync/windows.jsonee/maintained-apps/outputs/melodics/darwin.jsonee/maintained-apps/outputs/microsoft-teams/darwin.jsonee/maintained-apps/outputs/microsoft-teams/windows.jsonee/maintained-apps/outputs/mozilla-vpn/darwin.jsonee/maintained-apps/outputs/mozilla-vpn/windows.jsonee/maintained-apps/outputs/naps2/darwin.jsonee/maintained-apps/outputs/naps2/windows.jsonee/maintained-apps/outputs/nosql-workbench/darwin.jsonee/maintained-apps/outputs/nosql-workbench/windows.jsonee/maintained-apps/outputs/notepadexe/darwin.jsonee/maintained-apps/outputs/obs/darwin.jsonee/maintained-apps/outputs/only-switch/darwin.jsonee/maintained-apps/outputs/onlyoffice/darwin.jsonee/maintained-apps/outputs/picview/darwin.jsonee/maintained-apps/outputs/popclip/darwin.jsonee/maintained-apps/outputs/powerphotos/darwin.jsonee/maintained-apps/outputs/powershell/windows.jsonee/maintained-apps/outputs/prisma-browser/windows.jsonee/maintained-apps/outputs/pritunl/darwin.jsonee/maintained-apps/outputs/pritunl/windows.jsonee/maintained-apps/outputs/rider/darwin.jsonee/maintained-apps/outputs/rive/darwin.jsonee/maintained-apps/outputs/rustrover/windows.jsonee/maintained-apps/outputs/setapp/darwin.jsonee/maintained-apps/outputs/sidenotes/darwin.jsonee/maintained-apps/outputs/signal/darwin.jsonee/maintained-apps/outputs/signal/windows.jsonee/maintained-apps/outputs/snagit/darwin.jsonee/maintained-apps/outputs/sourcetree/darwin.jsonee/maintained-apps/outputs/superwhisper/darwin.jsonee/maintained-apps/outputs/tabby/darwin.jsonee/maintained-apps/outputs/trezor-suite/darwin.jsonee/maintained-apps/outputs/typora/windows.jsonee/maintained-apps/outputs/visual-studio-code/darwin.jsonee/maintained-apps/outputs/vivaldi/darwin.jsonee/maintained-apps/outputs/wechat/darwin.jsonee/maintained-apps/outputs/whatsapp/darwin.jsonee/maintained-apps/outputs/winlogbeat/windows.jsonee/maintained-apps/outputs/workflowy/darwin.jsonee/maintained-apps/outputs/zed/darwin.jsonee/maintained-apps/outputs/zed/windows.json
| "31b59062": "#!/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/Kiro CLI.app\"\ntrash $LOGGED_IN_USER '~/.kiro'\ntrash $LOGGED_IN_USER '~/.local/bin/kiro-cli'\ntrash $LOGGED_IN_USER '~/.local/bin/kiro-cli-chat'\ntrash $LOGGED_IN_USER '~/Library/Application Support/kiro-cli'\ntrash $LOGGED_IN_USER '~/Library/Caches/dev.kiro.cli'\ntrash $LOGGED_IN_USER '~/Library/Preferences/dev.kiro.cli.plist'\n", | ||
| "7bf3d706": "#!/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 'dev.kiro.cli'\nif [ -d \"$APPDIR/Kiro CLI.app\" ]; then\n\tsudo mv \"$APPDIR/Kiro CLI.app\" \"$TMPDIR/Kiro CLI.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Kiro CLI.app\" \"$APPDIR\"\nrelaunch_application 'dev.kiro.cli'\n" | ||
| "7bf3d706": "#!/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 'dev.kiro.cli'\nif [ -d \"$APPDIR/Kiro CLI.app\" ]; then\n\tsudo mv \"$APPDIR/Kiro CLI.app\" \"$TMPDIR/Kiro CLI.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Kiro CLI.app\" \"$APPDIR\"\nrelaunch_application 'dev.kiro.cli'\n", | ||
| "ed98f0de": "#!/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.amazon.codewhisperer.launcher'\nsudo rm -rf \"$APPDIR/Kiro CLI.app\"\ntrash $LOGGED_IN_USER '~/.kiro'\ntrash $LOGGED_IN_USER '~/.local/bin/kiro-cli'\ntrash $LOGGED_IN_USER '~/.local/bin/kiro-cli-chat'\ntrash $LOGGED_IN_USER '~/Library/Application Support/kiro-cli'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.amazon.codewhisperer'\ntrash $LOGGED_IN_USER '~/Library/Caches/dev.kiro.cli'\ntrash $LOGGED_IN_USER '~/Library/LaunchAgents/com.amazon.codewhisperer.launcher.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/dev.kiro.cli.plist'\ntrash $LOGGED_IN_USER '~/Library/WebKit/com.amazon.codewhisperer'\n" |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Repository files matching darwin.json in maintained-apps:\n'
fd -a 'darwin\.json$' ee/maintained-apps/outputs 2>/dev/null | sed 's#^\./##' | sort | head -200
printf '\nRelevant snippets for kiro-cli and setapp launchctl/trash paths:\n'
for f in \
ee/maintained-apps/outputs/kiro-cli/darwin.json \
ee/maintained-apps/outputs/setapp/darwin.json
do
echo "===== ${f} ====="
sed -n '1,160p' "${f}"
done
printf '\nSearch for launchctl asuser or launched in outputs:\n'
rg -n "launchctl|ConsoleUser|scutil|asuser|Library/LaunchAgents|LOGGED_IN_USER" ee/maintained-apps/outputs -g 'darwin.json' | head -200Repository: fleetdm/fleet
Length of output: 50370
🌐 Web query:
Apple launchctl asuser run command as specific user launchd domain LaunchAgents
💡 Result:
The launchctl asuser command is a legacy tool used to execute a command in the execution context (specifically the Mach bootstrap namespace, exception server, and security audit session) of a target user's bootstrap [1][2]. Usage: sudo launchctl asuser [args] Key Details: 1. Privileges: You must run this command as root (e.g., via sudo) for it to successfully access another user's bootstrap context [3][4]. 2. Target Identifier: It requires the target user's UID [5][6]. 3. Scope: It does not modify process credentials like UID or GID, nor does it adopt user-specific environment variables; it strictly affects the Mach bootstrap context [1][6]. Modern Alternatives: While asuser remains functional, it is considered a legacy subcommand [7]. Modern macOS administration (since OS X Yosemite and later) often favors the "launchctl 2.0" syntax, which explicitly targets domains [6][7]. To load or manage LaunchAgents for a specific user, it is now recommended to use the bootstrap and bootout commands targeting the gui/ domain [6][7]. Example of the modern approach: loggedInUserID=$(id -u ) /bin/launchctl bootstrap gui/"${loggedInUserID}" /Library/LaunchAgents/com.example.agent.plist This approach is generally more reliable in recent versions of macOS, as subcommands like asuser have been deprecated in practice in favor of direct domain management [7].
Citations:
- 1: https://leancrew.com/all-this/man/man1/launchctl.html
- 2: https://ss64.com/mac/launchctl.html
- 3: https://apple.stackexchange.com/questions/100829/how-to-launch-a-gui-application-in-another-users-graphical-session
- 4: https://stackoverflow.com/questions/24121303/run-launchctl-command-under-specific-user-using-nstask-in-os-x
- 5: https://bartreardon.github.io/2019/09/18/sudo-u-vs-launchctl-asuser.html
- 6: https://babodee.wordpress.com/2016/04/09/launchctl-2-0-syntax/
- 7: https://macblog.org/uid/
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import json, pathlib, re, zipfile, io
dirs = sorted(pathlib.Path("ee/maintained-apps/outputs").glob("*/darwin.json"))
print(f"darwin.json files inspected: {len(dirs)}")
for path in dirs[:200]:
data = json.loads(path.read_text())
if isinstance(data, list):
scripts = [entry.get("uninstaller_version_script") or entry.get("script") or "" for entry in data if isinstance(entry, dict)]
elif isinstance(data, dict):
scripts = [data.get("uninstaller_version_script") or data.get("script") or ""]
else:
continue
for idx, script in enumerate(scripts):
# Narrow to scripts containing these service targets and launchctl commands in remove_launchctl_service body/call paths.
has_label = "com.amazon.codewhisperer.launcher" in script or "com.setapp.DesktopClient.SetappAgent" in script or "com.setapp.DesktopClient.SetappAssistant" in script or "com.setapp.DesktopClient.SetappLauncher" in script or "com.setapp.DesktopClient.SetappUpdater" in script
if not has_label:
continue
needs_launchctl = any(pat in script for pat in ["launchctl list", "launchctl remove", "launchctl uninstall"])
uses_launchctl_asuser = "launchctl asuser" in script
uses_user_bootstrap = re.search(r"launchctl\s+(bootstrap|bootout)\s+gui/", script) is not None
# Capture representative launchctl lines around label mentions/inside helper
lines = script.splitlines()
hits = []
for n,l in enumerate(lines, 1):
if any(x in l for x in ["launchctl list", "launchctl remove", "launchctl uninstall", "# functions", "remove_launchctl_service"]):
hits.append((n,l))
print(f"===== {path} =====")
print(f"idx={idx}")
print(f"needs_launchctl={needs_launchctl}, launchctl_asuser={uses_launchctl_asuser}, user_bootstrap={uses_user_bootstrap}")
for n,l in hits[:50]:
print(f"{n}: {l}")
PYRepository: fleetdm/fleet
Length of output: 184
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'kiro-cli darwin entries matching kiro/codewhisperer:\n'
python3 - <<'PY'
import json, pathlib
for path in pathlib.Path("ee/maintained-apps/outputs/kiro-cli").glob("*.json"):
data=json.loads(path.read_text())
for i,entry in enumerate(data if isinstance(data,list) else [data]):
txt=entry.get("uninstaller_version_script") or entry.get("script") or ""
if any(x in txt for x in ["codewhisperer","kiro-cli","launchctl","LaunchAgents"]):
print(f"----- {path}:idx={i} -----")
for n,l in enumerate(txt.splitlines(),1):
if any(x in l for x in ["codewhisperer","kiro-cli","launchctl","LaunchAgents","LOGGED_IN_USER"]):
print(f"{n:4}: {l}")
PY
printf '\nsetapp darwin entries matching SetappAgent/SetappAssistant/SetappLauncher/SetappUpdater:\n'
python3 - <<'PY'
import json, pathlib
for path in pathlib.Path("ee/maintained-apps/outputs/setapp").glob("*.json"):
data=json.loads(path.read_text())
for i,entry in enumerate(data if isinstance(data,list) else [data]):
txt=entry.get("uninstaller_version_script") or entry.get("script") or ""
if any(x in txt for x in ["SetappAgent","SetappAssistant","SetappLauncher","SetappUpdater","launchctl","LaunchAgents"]):
print(f"----- {path}:idx={i} -----")
for n,l in enumerate(txt.splitlines(),1):
if any(x in l for x in ["SetappAgent","SetappAssistant","SetappLauncher","SetappUpdater","launchctl","LaunchAgents","LOGGED_IN_USER"]):
print(f"{n:4}: {l}")
PYRepository: fleetdm/fleet
Length of output: 294
Target the console user’s LaunchAgents domain during uninstall cleanup.
The root/system launchctl context used here does not operate on the logged-in user’s user LaunchAgents, so user-started helpers can remain registered after uninstall. Resolve the console UID and manage the /Library/LaunchAgents entries via the console user domain (launchctl asuser "$uid" or launchctl bootout gui/"$uid") before/while deleting each LaunchAgent plist.
Apply this to both kiro-cli and Setapp uninstall scripts.
📍 Affects 2 files
ee/maintained-apps/outputs/kiro-cli/darwin.json#L20-L20(this comment)ee/maintained-apps/outputs/setapp/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/kiro-cli/darwin.json` at line 20, Update
remove_launchctl_service in both ee/maintained-apps/outputs/kiro-cli/darwin.json
and ee/maintained-apps/outputs/setapp/darwin.json to resolve the logged-in
console user’s UID and remove /Library/LaunchAgents through that user’s
launchctl domain using launchctl asuser or bootout gui before deleting the
plist; retain system-domain handling for other entries.
| "b5794400": "#!/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.jetbrains.rider'\nif [ -d \"$APPDIR/Rider.app\" ]; then\n\tsudo mv \"$APPDIR/Rider.app\" \"$TMPDIR/Rider.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Rider.app\" \"$APPDIR\"\nrelaunch_application 'com.jetbrains.rider'\n", | ||
| "c52dae57": "#!/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/Rider.app\"\nsudo rm -rf 'rider'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Rider2026.1'\ntrash $LOGGED_IN_USER '~/Library/Caches/Rider2026.1'\ntrash $LOGGED_IN_USER '~/Library/Logs/Rider2026.1'\ntrash $LOGGED_IN_USER '~/Library/Preferences/jetbrains.rider.71e559ef.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/Rider2026.1'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.jetbrains.rider.savedState'\n" | ||
| "22db20ac": "#!/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/Rider.app\"\nsudo rm -rf 'rider'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Rider2026.2'\ntrash $LOGGED_IN_USER '~/Library/Caches/Rider2026.2'\ntrash $LOGGED_IN_USER '~/Library/Logs/Rider2026.2'\ntrash $LOGGED_IN_USER '~/Library/Preferences/jetbrains.rider.71e559ef.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/Rider2026.2'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.jetbrains.rider.savedState'\n", | ||
| "b5794400": "#!/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.jetbrains.rider'\nif [ -d \"$APPDIR/Rider.app\" ]; then\n\tsudo mv \"$APPDIR/Rider.app\" \"$TMPDIR/Rider.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Rider.app\" \"$APPDIR\"\nrelaunch_application 'com.jetbrains.rider'\n" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate file =="
git ls-files | rg 'ee/maintained-apps/outputs/rider/darwin.json|jetbrains|Uninstall|rider' || true
echo "== context in target file =="
if [ -f ee/maintained-apps/outputs/rider/darwin.json ]; then
wc -l ee/maintained-apps/outputs/rider/darwin.json
cat -n ee/maintained-apps/outputs/rider/darpin.json 2>/dev/null || sed -n '1,160p' ee/maintained-apps/outputs/rider/darwin.json | cat -n
else
echo "target file missing"
fi
echo "== all JetBrains paths in repo =="
rg -n "Library/(Application Support|Caches|JetBrains|Rider|Application Support/Rider|Caches/Rider)" ee maintained-apps maintained 2>/dev/null || trueRepository: fleetdm/fleet
Length of output: 50370
🌐 Web query:
JetBrains Rider macOS uninstall Application Support Caches JetBrains/Rider version
💡 Result:
To completely uninstall JetBrains Rider on macOS and remove its associated user directories, follow these steps according to official JetBrains documentation [1][2]. 1. Delete the Application: Move the JetBrains Rider application file from your Applications folder to the Trash [1][2]. 2. Remove User Directories: Delete the following folders in your user library (where {RiderVersion} corresponds to the specific version installed, such as Rider2026.1) [1][2]: - ~/Library/Application Support/JetBrains/Rider{RiderVersion} - ~/Library/Caches/JetBrains/Rider{RiderVersion} - ~/Library/Logs/JetBrains/Rider{RiderVersion} - ~/Library/Preferences/JetBrains/Rider{RiderVersion} Note that deleting the Caches directory will trigger a full solution analysis the next time you open a project, as this directory contains caches and local history files [3][4]. If you simply wish to clear space rather than perform a full uninstall, you can also use the built-in cleanup tool within Rider by navigating to Help | Delete Leftover IDE Directories to remove data associated with older versions [3]. Always ensure that all instances of Rider are closed before manually deleting these directories to avoid potential file locking issues [5].
Citations:
- 1: https://www.jetbrains.com/help/rider/Uninstall.html
- 2: https://www.jetbrains.com.cn/en-us/help/rider/Uninstall.html
- 3: https://www.jetbrains.com/help/rider/Directories_Used_by_the_IDE_to_Store_Settings_Caches_Plugins_and_Logs.html
- 4: https://rider-support.jetbrains.com/hc/en-us/articles/360005844600-Rider-takes-too-much-disk-space
- 5: https://rider-support.jetbrains.com/hc/en-us/articles/207803955-Where-are-the-ReSharper-cache-files-kept
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== rider darwin.json =="
if [ -f ee/maintained-apps/outputs/rider/darwin.json ]; then
wc -l ee/maintained-apps/outputs/rider/darwin.json
sed -n '1,80p' ee/maintained-apps/outputs/rider/darwin.json | cat -n
fi
echo "== exact Rider trash paths in output files =="
rg -n "JetBrains/Rider2026|Application Support/Rider2026|Caches/Rider2026|Preferences/JetBrains/Rider2026|Logs/JetBrains/Rider2026" ee/maintained-apps/outputs ee -g 'rider/**' 2>/dev/null || true
echo "== all rider-related user dirs in maintained apps =="
rg -n "Rider2026|Rider[0-9].*JetBrains|JetBrains/Rider" ee/maintained-apps/outputs ee/maintained-apps -g 'rider/**' 2>/dev/null || true
echo "== deterministic path check from installed script text =="
python3 - <<'PY'
from pathlib import Path
import json
p = Path("ee/maintained-apps/outputs/rider/darwin.json")
if p.exists():
data=json.loads(p.read_text())
first_val=list(data.values())[0]
for label in ["~/Library/Application Support/Rider2026.2", "~/Library/Caches/Rider2026.2"]:
print(f"{label}: {label in first_val}")
print("contains JetBrains/Rider2026.2:", "JetBrains/Rider2026.2" in first_val)
PYRepository: fleetdm/fleet
Length of output: 7285
Use Rider’s documented macOS user data paths.
Rider’s uninstall documentation removes data under ~/Library/Application Support/JetBrains/Rider2026.2, ~/Library/Caches/JetBrains/Rider2026.2, and ~/Library/Logs/JetBrains/Rider2026.2; the uninstall script now deletes ~/Library/Application Support/Rider2026.2 and ~/Library/Caches/Rider2026.2, so configuration, cache, and log data can be left behind.
🤖 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/rider/darwin.json` at line 20, Update the Rider
uninstall path handling to remove the documented JetBrains directories under
~/Library: Application Support/JetBrains/Rider2026.2,
Caches/JetBrains/Rider2026.2, and Logs/JetBrains/Rider2026.2. Replace the
existing Rider2026.2 paths that omit the JetBrains parent directory, and ensure
all three data locations are deleted.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Files:"
git ls-files 'ee/maintained-apps/outputs/**/darwin.json' | sed -n '1,120p'
echo
echo "Rider target excerpt:"
if [ -f ee/maintained-apps/outputs/rider/darwin.json ]; then
python3 - <<'PY'
import json
from pathlib import Path
p = Path('ee/maintained-apps/outputs/rider/darwin.json')
data = json.loads(p.read_text())
for key, value in data.items():
print(f'KEY {key}')
print(value)
PY
fi
echo
echo "Setapp target excerpt / relevant lines:"
if [ -f ee/maintained-apps/outputs/setapp/darwin.json ]; then
python3 - <<'PY'
import json
from pathlib import Path
p = Path('ee/maintained-apps/outputs/setapp/darwin.json')
data = json.loads(p.read_text())
for key, value in data.items():
print(f'KEY {key}')
lines = value.split('\n')
for i,line in enumerate(lines):
if any(s in line for s in ['Setapp', 'rm', 'bash', 'sudo rm', 'Application Scripts']):
print(f'{i+1}: {line}')
PY
fi
echo
echo "Search for similar quit logic in nearby output files:"
rg -n "quit_and_track_application|relaunch_application|killall|pkill|launchctl Kill|rm -rf|mv |open -b" ee/maintained-apps/outputs -g 'darwin.json' | sed -n '1,240p'Repository: fleetdm/fleet
Length of output: 12881
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Setapp uninstall ref excerpt:"
python3 - <<'PY'
import json
from pathlib import Path
p = Path('ee/maintained-apps/outputs/setapp/darwin.json')
data = json.loads(p.read_text())
for key, value in data.items():
if key == 'refs':
continue
print(key, type(value).__name__, value)
print('--- refs ---')
for ref in ['5b4e5e38', '9ef05eb6']:
# use first matching ref containing relevant commands if present
pass
# locate the uninstall ref by references in version metadata
for k,v in data.items():
if isinstance(v, list):
for item in v:
if isinstance(item, dict) and (item.get('version') == '1') and (item.get('uninstall_script_ref') or item.get('install_script_ref')):
print(k, item)
PY
echo
echo "Find Setapp refs:"
python3 - <<'PY'
import json
p = Path('ee/maintained-apps/outputs/setapp/darwin.json')
data = json.loads(p.read_text())
values = []
for k, v in data.items():
if k == 'refs':
values.append((k, v))
elif isinstance(v, list):
for x in v:
if isinstance(x, dict) and 'uninstall_script_ref' in str(x) or 'install_script_ref' in str(x):
values.append((k, v))
for k, v in values:
if isinstance(v, dict):
for ref_id, script in v.items():
print(f"REF {ref_id}")
lines = script.splitlines()
for i in range(min(len(lines), 220)):
if any(s in lines[i].lower() for s in ['setapp', 'rm -rf', 'trash', 'applications']):
print(f"{i+1}: {lines[i]}")
PY
echo
echo "Current uninstall scripts containing Rider.app or Setapp.app removal:"
rg -n "Rider\\.app|Setapp\\.app|rm -rf|trash|quit_and_track_application|relaunch_application" ee/maintained-apps/outputs -g 'darwin.json' -g '*darwin.json' | sed -n '1,260p'
echo
echo "Validate installed/uninstalled script ordering behavior via static ordering around removal lines:"
python3 - <<'PY'
import json, re
from pathlib import Path
for rel in ['rider', 'setapp']:
p = Path(f'ee/maintained-apps/outputs/{rel}/darwin.json')
data = json.loads(p.read_text())
ref_map=data.get('refs',{})
for k,v in data.items():
if not isinstance(v, list): continue
for item in v:
if not isinstance(item, dict): continue
u=item.get('uninstall_script_ref')
if not u: continue
script=ref_map.get(u,'')
print(f"--- {rel} uninstall {u} ---")
lines=script.splitlines()
terms=[]
for i,l in enumerate(lines):
if any(s in l.lower() for s in ['rm -rf', 'trash', 'quit_and_track_application', 'relaunch_application', 'killall', 'pkill', 'launchctl kill']):
terms.append((i+1,l))
for i,l in terms:
print(f"{i}: {l}")
rem=[(i,l) for i,l in terms if 'rm -rf' in l or l.startswith('trash ') or 'trash' in l.lower()]
print("removal_count", len(rem))
PYRepository: fleetdm/fleet
Length of output: 942
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import json
from pathlib import Path
def show_app(name):
p = Path(f'ee/maintained-apps/outputs/{name}/darwin.json')
data = json.loads(p.read_text())
print(f"--- {name} refs count ---")
print(len(data.get('refs', {})))
for key, script in data.get('refs', {}).items():
if 'Rider.app' in script or 'Setapp.app' in script or 'Kill' in script or 'quit_and_track' in script:
lines = script.splitlines()
print(f"REF {key} relevant line count", sum('Rider' in l or 'Setapp' in l or 'rm -rf' in l or 'trash' in l.lower() or 'kill' in l.lower() for l in lines))
for i,l in enumerate(lines):
if any(term in l for term in ['Rider.app', 'Setapp.app', 'rm -rf', 'killall', 'pkill', 'launchctl kill', 'kill', 'kill -15', 'quit_and_track_application', 'relaunch_application', "trash $LOGGED_IN_USER"]):
print(f"{i+1}: {l}")
for k,v in data.items():
if not isinstance(v, list): continue
for item in v:
if isinstance(item, dict) and 'uninstall_script_ref' in item:
print("version", item.get('version'), "uninstall_script_ref", item['uninstall_script_ref'])
for name in ['rider', 'setapp']:
show_app(name)
PY
echo
echo "All uninstall refs mentioning bundle removal without quit helper:"
python3 - <<'PY'
import json
from pathlib import Path
def has_unquit_bundle_removal(script):
removals = [l for l in script.splitlines() if 'rm -rf' in l and ('Rider.app' in l or 'Setapp.app' in l)]
quit_helpers = any(h in script for h in ['quit_and_track_application', 'relaunch_application', 'killall', 'pkill', 'launchctl kill'])
return bool(removals) and not quit_helpers
for name in ['rider', '1password', 'slack']:
p = Path(f'ee/maintained-apps/outputs/{name}/darwin.json')
if not p.exists(): continue
data=json.loads(p.read_text())
for i,v in enumerate(data.get('refs',{}).items(),1):
print(i, v[0], has_unquit_bundle_removal(v[1]))
PYRepository: fleetdm/fleet
Length of output: 2700
Quit Rider before removing its bundle.
ee/maintained-apps/outputs/rider/darwin.json version 2026.2 uses uninstall ref 22db20ac, which deletes $APPDIR/Rider.app/'rider' without the bounded quit_and_track_application() flow already present in the install script. A running Rider process can survive with its application bundle removed.
Use a bounded quit path before the bundle cleanup, and apply the same pattern to the Setapp uninstall path (ee/maintained-apps/outputs/setapp/darwin.json uninstall ref 9ef05eb6) if the same concern is intended there.
📍 Affects 2 files
ee/maintained-apps/outputs/rider/darwin.json#L20-L20(this comment)ee/maintained-apps/outputs/setapp/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/rider/darwin.json` at line 20, Update the Rider
uninstall script in ee/maintained-apps/outputs/rider/darwin.json at line 20 to
invoke the bounded quit_and_track_application() flow for com.jetbrains.rider
before deleting or moving Rider.app, preserving the existing relaunch tracking
behavior as applicable. Apply the same pre-cleanup quit pattern to the Setapp
uninstall script in ee/maintained-apps/outputs/setapp/darwin.json at line 20 if
its uninstall path removes a running application bundle.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Files:"
git ls-files | rg '(^|/)rider/.+\.json$|^\Qee/maintained-apps/outputs/rider/darwin.json\E|uninstall|rider' | head -200
echo
echo "Inspect target:"
if [ -f ee/maintained-apps/outputs/rider/darwin.json ]; then
wc -l ee/maintained-apps/outputs/rider/darwin.json
sed -n '1,220p' ee/maintained-apps/outputs/rider/darwin.json | sed -n '1,220p'
else
echo "missing ee/maintained-apps/outputs/rider/darwin.json"
fi
echo
echo "Search uninstall scripts / removal patterns:"
rg -n "Rider\.app|rider|uninstall|quit_and_track_application|relaunch_application|happens?|rm|remove|mv" . --glob '*.json' --glob '*.sh' --glob '*.ts' --glob '*.js' -S | head -300Repository: fleetdm/fleet
Length of output: 344
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Files:"
git ls-files | rg '(^|/)rider/.+\.json$|^ee/maintained-apps/outputs/rider/darwin.json$|uninstall|rider' | head -300
echo
if [ -f ee/maintained-apps/outputs/rider/darwin.json ]; then
echo "Inspect target file length:"
wc -l ee/maintained-apps/outputs/rider/darwin.json
echo
echo "Parsed script contents:"
python3 - <<'PY' >/tmp/rider_darwin.json.txt
import json
from pathlib import Path
p = Path('ee/maintained-apps/outputs/rider/darwin.json')
data = json.loads(p.read_text())
print(json.dumps(data.get('script'), indent=2))
PY
sed -n '1,240p' /tmp/rider_darwin.json.txt
else
echo "missing ee/maintained-apps/outputs/rider/darwin.json"
fi
echo
echo "Search uninstall/scripts for Rider removal patterns:"
rg -n "Rider\.app|quit_and_track_application|relaunch_application|open -b|com\.jetbrains\.rider|uninstall|happens?|rm|remove|mv|sudo mv|sudo rm" . --glob '*.json' --glob '*.sh' --glob '*.ts' --glob '*.js' --glob '*.ps1' --glob '*.py' -S | head -400Repository: fleetdm/fleet
Length of output: 50369
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Files:"
git ls-files | rg '(^|/)rider/.+\.json$|^ee/maintained-apps/outputs/rider/darwin.json$|uninstall|rider' | head -300
echo
if [ -f ee/maintained-apps/outputs/rider/darwin.json ]; then
echo "Inspect target file length:"
wc -l ee/maintained-apps/outputs/rider/darwin.json
echo
echo "Parsed script contents:"
python3 - <<'PY' >/tmp/rider_darwin.json.txt
import json
from pathlib import Path
p = Path('ee/maintained-apps/outputs/rider/darwin.json')
data = json.loads(p.read_text())
print(json.dumps(data.get('script'), indent=2))
PY
sed -n '1,240p' /tmp/rider_darwin.json.txt
else
echo "missing ee/maintained-apps/outputs/rider/darwin.json"
fi
echo
echo "Search uninstall/scripts for Rider removal patterns:"
rg -n "Rider\.app|quit_and_track_application|relaunch_application|open -b|com\.jetbrains\.rider|uninstall|happens?|rm|remove|mv|sudo mv|sudo rm" . --glob '*.json' --glob '*.sh' --glob '*.ts' --glob '*.js' --glob '*.ps1' --glob '*.py' -S | head -400
echo
echo "Check uninstall context around matching files:"
matching=$(git ls-files | rg '(^|/)rider/.+\.json$|^ee/maintained-apps/outputs/rider/darwin.json$|uninstall|rider' | grep -E '(uninstall|darwin\.json|.*rider.*\.json$)' || true)
for f in $matching; do
echo "===== $f ====="
rg -n "Rider\.app|Rider.app|quit_and_track_application|relaunch_application|open -b|com\.jetbrains\.rider|happens?|rm|remove|mv|sudo mv|sudo rm" "$f" -S || true
doneRepository: fleetdm/fleet
Length of output: 50370
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Raw target JSON:"
cat -n ee/maintained-apps/outputs/rider/darwin.json
echo
echo "Input/output files and sizes:"
for f in \
ee/maintained-apps/inputs/homebrew/rider.json \
ee/maintained-apps/inputs/winget/rider.json \
ee/maintained-apps/outputs/rider/darwin.json \
ee/maintained-apps/outputs/rider/windows.json
do
echo "===== $f ====="
cat -n "$f"
done
echo
echo "Focused relevant matches only:"
rg -n "Rider\.app|quit_and_track_application|relaunch_application|open -b|com\.jetbrains\.rider|rm -rf /Applications/Rider\.app|mv /Applications/Rider\.app|uninstall_script|rider" ee/maintained-apps ee/mdm server/pkg server/cmd server/web --glob '*.json' --glob '*.ts' --glob '*.go' -S | head -400Repository: fleetdm/fleet
Length of output: 50370
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "raw target JSON bytes/size:"
wc -c ee/maintained-apps/outputs/rider/darwin.json
cat ee/maintained-apps/outputs/rider/darwin.json
echo
echo "rider files:"
for f in ee/maintained-apps/inputs/homebrew/rider.json ee/maintained-apps/inputs/winget/rider.json ee/maintained-apps/outputs/rider/darwin.json ee/maintained-apps/outputs/rider/windows.json; do
echo "===== $f ====="
cat -n "$f"
done
echo
echo "focused app/removal lines only:"
rg -n "quit_and_track|rider|Rider\.app|rm -rf|uninstall_script_path|uninstall_script_ref" \
ee/maintained-apps/inputs ee/maintained-apps/outputs ee/mdm \
--glob '*.json' --glob '*.ts' --glob '*.sh' --glob '*.ps1' --glob '*.go' -S | head -400Repository: fleetdm/fleet
Length of output: 50370
🏁 Script executed:
#!/bin/bash
set -euo pipefail
base="$(mktemp -d)"
for f in ee/maintained-apps/inputs/homebrew/rider.json \
ee/maintained-apps/inputs/winget/rider.json \
ee/maintained-apps/outputs/rider/darwin.json \
ee/maintained-apps/outputs/rider/windows.json; do
echo "===== $f ====="
python3 - <<'PY' "$f"
import json, pathlib, sys
p=pathlib.Path(sys.argv[1])
text=p.read_text()
if p.suffix==".json":
data=json.loads(text)
if "script" in data:
print(data["script"])
else:
print(json.dumps(data, indent=2))
else:
print(text)
PY
echo
done
echo "Focused removal/script entries only:"
python3 - <<'PY'
import json, pathlib, re
for p in pathlib.Path("ee/maintained-apps/inputs").rglob("*.json"):
try:
data=json.loads(p.read_text())
except Exception:
continue
txt = json.dumps(data)
if re.search(r'(?i)\brider\b|com\.jetbrains\.rider', txt):
print(f"\n{p}")
for k in ["label","script_path","uninstall_script_path","bundle_id","app_id","uninstall_script_ref"]:
if k in data or any(k in json.dumps(v) for v in (data.values() if isinstance(data, dict) else [])):
print(k, ":", data.get(k) or (data.get("uninstall_script_refs") or data.get("install_script_refs")))
for p in pathlib.Path("ee/maintained-apps/outputs").rglob("*.json"):
try:
data=json.loads(p.read_text())
except Exception:
continue
txt = json.dumps(data)
if re.search(r'(?i)\brider\b|com\.jetbrains\.rider|Rider\.app', txt):
print(f"\n{p}")
for k,v in data.items():
if isinstance(v,str) and re.search(r'(?i)\brider\b|com\.jetbrains\.rider|Rider\.app', v):
print(k, ":", v[:2000])
PYRepository: fleetdm/fleet
Length of output: 12458
Quit Rider before deleting its bundle.
The macOS uninstall script directly runs sudo rm -rf "$APPDIR/Rider.app" without first prompting or terminating a running Rider process, so an open instance can remain alive after the bundle is gone. Reuse the bounded quit flow from the install script before removal.
🤖 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/rider/darwin.json` at line 20, The uninstall flow
must terminate Rider before removing its application bundle. Reuse the existing
bounded quit logic from quit_and_track_application, or invoke that shared
helper, immediately before sudo rm -rf "$APPDIR/Rider.app"; preserve the timeout
behavior and ensure removal proceeds only after the quit attempt.
| "version": "26.7.2", | ||
| "queries": { | ||
| "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'io.trezor.TrezorSuite';", | ||
| "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'io.trezor.TrezorSuite' AND version_compare(bundle_short_version, '26.6.1') < 0);" | ||
| "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'io.trezor.TrezorSuite' AND version_compare(bundle_short_version, '26.7.2') < 0);" | ||
| }, | ||
| "installer_url": "https://data.trezor.io/suite/releases/desktop/latest/Trezor-Suite-26.6.1-mac-arm64.dmg", | ||
| "installer_url": "https://data.trezor.io/suite/releases/desktop/latest/Trezor-Suite-26.7.2-mac-arm64.dmg", |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Tracked trezor suite manifests:"
git ls-files | grep -F 'ee/maintained-apps/outputs/trezor-suite/darwin.json' || true
echo
echo "Relevant manifest section:"
if [ -f ee/maintained-apps/outputs/trezor-suite/darwin.json ]; then
sed -n '1,80p' ee/maintained-apps/outputs/trezor-suite/darwin.json | cat -n
fi
echo
echo "Search for Trezor release URL patterns in repo:"
rg -n "trezor-suite|Trezor-Suite|data\.trezor\.io/suite/releases|latest/" . || trueRepository: fleetdm/fleet
Length of output: 50370
🌐 Web query:
data.trezor.io/suite/releases/desktop/latest directory indexing Trezor Suite releases
💡 Result:
The URL https://data.trezor.io/suite/releases/desktop/latest/ is an official directory index maintained by Trezor that provides access to the latest desktop releases of the Trezor Suite application [1][2]. This directory is primarily used for the following purposes: 1. Auto-update Mechanism: The Trezor Suite desktop application uses an auto-updater that references these files to check for, download, and verify the latest software updates [3]. The directory contains YAML metadata files (e.g., latest.yml, latest-mac.yml, latest-linux.yml) that specify the version and update information required by the application [1][3][4]. 2. Third-Party Integrations: Open-source package managers and distribution maintainers (such as NixOS and Homebrew) use this directory to automate the tracking and packaging of the latest Trezor Suite releases [5][6]. By referencing these metadata files, they can programmatically determine the current version and verify updates [5][6]. While this directory is an official source of distribution for binary files and metadata, users are generally advised to download and verify Trezor Suite through the official website (https://trezor.io/trezor-suite) or the official GitHub repository (https://github.com/trezor/trezor-suite/releases) to ensure security and authenticity [7]. The directory index provides a raw, machine-readable view of these releases [1][2].
Citations:
- 1: https://data.trezor.io/suite/releases/desktop/latest/
- 2: https://data.trezor.io/suite/releases/desktop/
- 3: https://docs.trezor.io/trezor-suite/releases/desktop_updates.html
- 4: https://data.trezor.io/suite/releases/desktop/v25.6.3/
- 5: https://github.com/NixOS/nixpkgs/blob/38a3664e/pkgs/by-name/tr/trezor-suite/update.sh
- 6: https://github.com/Homebrew/homebrew-cask/blob/47817d96ba845ccedf309ed3f1e820076cecd0ba/Casks/t/trezor-suite.rb
- 7: https://trezor.io/guides/trezor-suite/download-verify-trezor-suite
🌐 Web query:
data.trezor.io/suite/releases/desktop/v26.7.2 Trezor Suite 26.7.2
💡 Result:
Trezor Suite version 26.7.2 is the official desktop update released in July 2026 [1][2]. This update includes several new features and improvements, such as [1]: - Tron (TRX) staking support. - Ability to cancel pending EVM transactions. - Options to view and edit the nonce in the EVM send form. - A new preview step in the Buy flow. - SLIP24 support for Ripple transactions. - A WalletConnect button in the account menu. Additionally, the update addresses various bug fixes, including resolutions for issues with EVM transaction management (such as preventing cancellations or speed-ups when a nonce gap exists) and improvements to token search results and Bitcoin Cash address prefixes [1]. Users are encouraged to update their desktop application by following the on-screen instructions within Trezor Suite [1]. For those who are not yet using the application, the latest version can be downloaded from the official Trezor website at https://trezor.io/trezor-suite [1][3]. Updates are rolled out in stages, so some users may not be prompted immediately [1].
Citations:
- 1: https://trezor.io/other/product-updates/trezor-suite-updates/trezor-suite-update-july-2026
- 2: https://www.reddit.com/r/TREZOR/comments/1v3lssx/trezor_suite_trezor_firmware_july_2026_update_is/
- 3: https://trezor.io/guides/trezor-suite/download-verify-trezor-suite
🌐 Web query:
data.trezor.io/suite/releases/desktop/latest/index.yml Trezor Suite latest.yml
💡 Result:
The file path data.trezor.io/suite/releases/desktop/latest/index.yml is not a direct file, but rather part of a directory index on Trezor's update server [1]. In the context of Trezor Suite desktop releases, latest.yml (and its variations like latest-mac.yml and latest-linux.yml) serves as a metadata manifest file used by the application's auto-updater [2]. These YAML files contain critical information such as the current version number and SHA512 hashes required for verifying the integrity of update binaries [3]. Key details regarding these files: - Purpose: They provide the information necessary for the Trezor Suite desktop client to check for, download, and verify new software updates [2][3]. - Structure: The latest.yml file is generally used for Windows updates, while platform-specific variants (e.g., latest-mac.yml, latest-linux.yml) handle updates for other operating systems [1][2]. - Accessibility: These files are hosted publicly at https://data.trezor.io/suite/releases/desktop/latest/ [1]. - Technical Integration: Developers and automated systems, such as package maintainers (e.g., NixOS), use these files to programmatically track the latest release versions and verify file checksums [3]. For official technical documentation on how these updates and manifest files are handled, you can refer to the Trezor Suite developer documentation regarding desktop updates [2][4].
Citations:
- 1: https://data.trezor.io/suite/releases/desktop/latest/
- 2: https://docs.trezor.io/trezor-suite/releases/desktop_updates.html
- 3: https://github.com/NixOS/nixpkgs/blob/38a3664e/pkgs/by-name/tr/trezor-suite/update.sh
- 4: https://docs.trezor.io/trezor-suite/releases/index.html
🌐 Web query:
trezor data.trezor.io/suite/releases/desktop/ directory structure versioned releases latest.yml
💡 Result:
The Trezor Suite desktop release repository at https://data.trezor.io/suite/releases/desktop/ follows a structured organization to manage versioned releases and auto-updates [1]. Directory Structure The root directory contains: - A latest/ directory, which holds the metadata and binaries for the most recent version of Trezor Suite [1][2]. - Individual versioned directories (e.g., v26.3.3/, v25.6.3/), which contain the binaries, blockmaps, and detached signature files (.asc) for specific past releases [1][3][4]. - A canary/ directory for experimental or pre-release builds [1]. Within each versioned directory (and the latest/ folder), you will typically find the following files: - Application binaries for various platforms (e.g., .AppImage for Linux, .dmg/.zip for macOS, .exe for Windows) [3][4]. - Corresponding signature files (e.g., ...AppImage.asc) used for verification [3][4]. - Blockmap files (e.g., ...blockmap) used to support efficient updates [3][4]. - YAML metadata files (e.g., latest.yml, latest-mac.yml, latest-linux.yml) which are critical for the auto-update mechanism [2][3]. latest.yml and Auto-Updates The latest.yml files (and their platform-specific variants like latest-linux.yml or latest-mac.yml) serve as the feed for the Trezor Suite auto-updater [2][5]. When the Trezor Suite desktop application checks for updates, it queries these YAML files to determine if a newer version is available [5]. The latest.yml file typically contains information such as: - The version number of the latest release. - The file path or URL to the update binary. - Cryptographic hashes (often SHA-512) required to verify the integrity of the downloaded update package. This structure allows the desktop application to automatically identify, download, and verify new versions without user intervention beyond confirming the update [5]. Developers can also mock this update process in a development environment by hosting their own local versions of these directories and YAML files and pointing the Suite configuration to them [5].
Citations:
- 1: https://data.trezor.io/suite/releases/desktop/
- 2: https://data.trezor.io/suite/releases/desktop/latest/
- 3: https://data.trezor.io/suite/releases/desktop/v26.2.3/
- 4: https://data.trezor.io/suite/releases/desktop/v25.6.3/
- 5: https://docs.trezor.io/trezor-suite/releases/desktop_updates.html
Pin the Trezor installer URL to the immutable release directory.
This manifest pins 26.7.2 plus the SHA-256, but installer_url points at Trezor’s mutable latest directory. If Trezor updates latest, the pinned checksum can stop matching the downloaded bytes. Use the versioned directory URL, e.g. https://data.trezor.io/suite/releases/desktop/26.7.2/Trezor-Suite-26.7.2-mac-arm64.dmg, after confirming the path exists.
🤖 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/trezor-suite/darwin.json` around lines 4 - 9,
Update the installer_url for the Trezor Suite 26.7.2 manifest to use the
immutable versioned release directory instead of latest, preserving the existing
filename and checksum alignment; confirm the versioned URL path exists before
applying the change.
| "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'dev.zed.Zed' AND version_compare(bundle_short_version, '1.12.0') < 0);" | ||
| }, | ||
| "installer_url": "https://zed.dev/api/releases/stable/1.11.3/Zed-aarch64.dmg", | ||
| "installer_url": "https://zed.dev/api/releases/stable/1.12.0/Zed-aarch64.dmg", |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
rg -n 'aarch64|x86_64|"architecture"|"arch"' \
ee/maintained-apps/outputs/zed ee/maintained-appsRepository: fleetdm/fleet
Length of output: 29692
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Zed output files:"
ls -l ee/maintained-apps/outputs/zed/ || true
echo
cat -n ee/maintained-apps/outputs/zed/darwin.json
echo
cat -n ee/maintained-apps/outputs/zed/windows.json
echo
echo "Search for zed app name and architecture restriction:"
rg -n '\\bzed\\b|architecture|arch|target|darwin|aarch64|x86_64' ee/maintained-apps -g '!**/.git/**' | head -n 200Repository: fleetdm/fleet
Length of output: 50369
🌐 Web query:
zed dev macos x86_64 aarch64 release downloads
💡 Result:
Zed is available for macOS on both Apple Silicon (aarch64) and Intel (x86_64) architectures [1][2][3]. Both architectures are supported natively, meaning no Rosetta translation is required [3]. You can download the Zed editor for macOS through the following official channels: 1. Official Website: You can download the latest stable version directly from the official download page at https://zed.dev/download [4][1]. The download is provided as a.dmg file, which you can open to install the application to your /Applications folder [2][3]. 2. Homebrew: For macOS users who prefer package managers, Zed can be installed via Homebrew [2][5]. - To install the stable version: brew install --cask zed [2][5] - To install the preview version: brew install --cask zed@preview [2][5] The editor supports macOS 10.15 (Catalina) and newer versions [1][2][3]. After the initial manual installation, Zed includes a built-in mechanism to check for and apply updates [1][5]. For advanced users and developers, specific release binaries for different architectures can also be found on the project's official GitHub releases page [6].
Citations:
- 1: https://zed.dev/docs/installation
- 2: https://zed.dev/docs/macos
- 3: https://www.deployhq.com/guides/zed
- 4: https://zed.dev/download
- 5: https://github.com/zed-industries/zed/blob/b0911ccc/docs/src/installation.md
- 6: https://github.com/zed-industries/zed/releases
Use an architecture-specific Zed macOS installer or a universal artifact.
zed/darwin.json currently points only to Zed-aarch64.dmg, while Zed supports both Apple Silicon and Intel macOS and provides separate Zed-x86_64 downloads. Add an x86_64 path or use a universal installer so Intel clients do not receive an incompatible package.
🤖 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/zed/darwin.json` at line 9, Update the
installer_url in darwin.json to use a universal Zed macOS artifact or the
appropriate architecture-specific package selection, ensuring both Apple Silicon
and Intel clients receive compatible installers instead of only Zed-aarch64.dmg.
…, revert Pritunl (mac) - typora/windows: revert 1.14.7 -> 1.14.1 and freeze winget input (installer registers as 1.14.1 in the registry, so 1.14.7 is never found by osquery) - onlyoffice/darwin: installer is a DMG, not a ZIP; set installer_format=dmg and regenerate so the install script uses hdiutil instead of unzip - pritunl/darwin: revert 1.3.4696.56 -> 1.3.4686.95 (the release installs a bundle still reporting 1.3.4686.95)
Script Diff Resultsee/maintained-apps/outputs/advanced-installer/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/akiflow/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/amie/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/anytype/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/aptakube/windows.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-sam-cli/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/bettertouchtool/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/betterzip/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/beyond-compare/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/brave-browser/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/brave-browser/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/burp-suite/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cleanmymac/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/clop/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/comet/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cursor/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dataflare/darwin.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/datagrip/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/datagrip/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dockside/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/drawio/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/enpass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/fellow/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/fellow/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===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/firefox@nightly/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/firefox@nightly/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/google-ads-editor/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/google-gemini/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/granola/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/granola/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/groove-omnidialer/darwin.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/hwmonitor/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/kiro-cli/darwin.json=== Install Script (no changes) ===
=== Uninstall // 31b59062 -> ed98f0de ===
--- /tmp/old.HfbRDX 2026-07-23 15:45:39.863962505 +0000
+++ /tmp/new.T573rE 2026-07-23 15:45:39.863962505 +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,10 +122,14 @@
fi
}
+remove_launchctl_service 'com.amazon.codewhisperer.launcher'
sudo rm -rf "$APPDIR/Kiro CLI.app"
trash $LOGGED_IN_USER '~/.kiro'
trash $LOGGED_IN_USER '~/.local/bin/kiro-cli'
trash $LOGGED_IN_USER '~/.local/bin/kiro-cli-chat'
trash $LOGGED_IN_USER '~/Library/Application Support/kiro-cli'
+trash $LOGGED_IN_USER '~/Library/Caches/com.amazon.codewhisperer'
trash $LOGGED_IN_USER '~/Library/Caches/dev.kiro.cli'
+trash $LOGGED_IN_USER '~/Library/LaunchAgents/com.amazon.codewhisperer.launcher.plist'
trash $LOGGED_IN_USER '~/Library/Preferences/dev.kiro.cli.plist'
+trash $LOGGED_IN_USER '~/Library/WebKit/com.amazon.codewhisperer'ee/maintained-apps/outputs/kiro/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/kiro/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/lookaway/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/macwhisper/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/marsedit/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/melodics/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/microsoft-teams/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/microsoft-teams/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/mozilla-vpn/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/mozilla-vpn/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/naps2/darwin.json=== Install // 54ba1114 -> 27c40399 ===
--- /tmp/old.E293CW 2026-07-23 15:45:40.391957493 +0000
+++ /tmp/new.mYEpiB 2026-07-23 15:45:40.391957493 +0000
@@ -96,5 +96,5 @@
# install pkg files
quit_and_track_application 'com.naps2.desktop'
-sudo installer -pkg "$TMPDIR/naps2-8.3.1-mac-arm64.pkg" -target /
+sudo installer -pkg "$TMPDIR/naps2-8.3.2-mac-arm64.pkg" -target /
relaunch_application 'com.naps2.desktop'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/naps2/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nosql-workbench/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nosql-workbench/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/notepadexe/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/obs/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/only-switch/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/onlyoffice/darwin.json=== Install // 5beeff19 -> e2c9162f ===
--- /tmp/old.OesSlj 2026-07-23 15:45:40.705954513 +0000
+++ /tmp/new.DtbIQY 2026-07-23 15:45:40.705954513 +0000
@@ -95,7 +95,10 @@
# extract contents
-unzip "$INSTALLER_PATH" -d "$TMPDIR"
+MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
+yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
+sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
+hdiutil detach "$MOUNT_POINT" || true
# copy to the applications folder
quit_and_track_application 'asc.onlyoffice.editors-helper-renderer'
if [ -d "$APPDIR/ONLYOFFICE.app" ]; then
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/picview/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/popclip/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/powerphotos/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/powershell/windows.json=== Install Script (no changes) ===
=== Uninstall // 0995d374 -> 06cf76b8 ===
--- /tmp/old.2q5qtq 2026-07-23 15:45:40.896952700 +0000
+++ /tmp/new.UhGpHS 2026-07-23 15:45:40.896952700 +0000
@@ -1,4 +1,4 @@
-$product_code = '{7B031DCF-BDCE-47D6-89B9-4C558D76E773}'
+$product_code = '{92D9A5DC-8C64-40D5-B1BC-98DB9C7FDB7F}'
$timeoutSeconds = 300 # 5 minute timeout
# Fleet uninstalls app using product code that's extracted on uploadee/maintained-apps/outputs/prisma-browser/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/pritunl/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rider/darwin.json=== Install Script (no changes) ===
=== Uninstall // c52dae57 -> 22db20ac ===
--- /tmp/old.sU528R 2026-07-23 15:45:41.021951514 +0000
+++ /tmp/new.G0f3w7 2026-07-23 15:45:41.021951514 +0000
@@ -54,9 +54,9 @@
sudo rm -rf "$APPDIR/Rider.app"
sudo rm -rf 'rider'
-trash $LOGGED_IN_USER '~/Library/Application Support/Rider2026.1'
-trash $LOGGED_IN_USER '~/Library/Caches/Rider2026.1'
-trash $LOGGED_IN_USER '~/Library/Logs/Rider2026.1'
+trash $LOGGED_IN_USER '~/Library/Application Support/Rider2026.2'
+trash $LOGGED_IN_USER '~/Library/Caches/Rider2026.2'
+trash $LOGGED_IN_USER '~/Library/Logs/Rider2026.2'
trash $LOGGED_IN_USER '~/Library/Preferences/jetbrains.rider.71e559ef.plist'
-trash $LOGGED_IN_USER '~/Library/Preferences/Rider2026.1'
+trash $LOGGED_IN_USER '~/Library/Preferences/Rider2026.2'
trash $LOGGED_IN_USER '~/Library/Saved Application State/com.jetbrains.rider.savedState'ee/maintained-apps/outputs/rive/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rustrover/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/setapp/darwin.json=== Install Script (no changes) ===
=== Uninstall // e23bd29d -> 9ef05eb6 ===
--- /tmp/old.jJX3to 2026-07-23 15:45:41.145950337 +0000
+++ /tmp/new.PSi2Ex 2026-07-23 15:45:41.145950337 +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,10 +122,19 @@
fi
}
+remove_launchctl_service 'com.setapp.DesktopClient.SetappAgent'
+remove_launchctl_service 'com.setapp.DesktopClient.SetappAssistant'
+remove_launchctl_service 'com.setapp.DesktopClient.SetappLauncher'
+remove_launchctl_service 'com.setapp.DesktopClient.SetappUpdater'
sudo rm -rf "$APPDIR/Setapp.app"
trash $LOGGED_IN_USER '~/Library/Application Scripts/com.setapp.DesktopClient.SetappAgent.FinderSyncExt'
+trash $LOGGED_IN_USER '~/Library/Application Support/Setapp*'
trash $LOGGED_IN_USER '~/Library/Caches/com.setapp.DesktopClient'
trash $LOGGED_IN_USER '~/Library/Caches/com.setapp.DesktopClient.SetappAgent'
+trash $LOGGED_IN_USER '~/Library/Containers/com.setapp.DesktopClient.SetappAgent.FinderSyncExt'
+trash $LOGGED_IN_USER '~/Library/HTTPStorages/com.setapp.DesktopClient*'
+trash $LOGGED_IN_USER '~/Library/LaunchAgents/com.setapp.DesktopClient.*plist'
trash $LOGGED_IN_USER '~/Library/Logs/Setapp'
+trash $LOGGED_IN_USER '~/Library/Preferences/com.setapp.DesktopClient.plist'
trash $LOGGED_IN_USER '~/Library/Preferences/com.setapp.DesktopClient.SetappAgent.plist'
trash $LOGGED_IN_USER '~/Library/Saved Application State/com.setapp.DesktopClient.savedState'ee/maintained-apps/outputs/sidenotes/darwin.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/snagit/darwin.json=== Install Script (no changes) ===
=== Uninstall // b52ff2b2 -> 59bfdeae ===
--- /tmp/old.PYfEPQ 2026-07-23 15:45:41.314948733 +0000
+++ /tmp/new.mjcMPW 2026-07-23 15:45:41.314948733 +0000
@@ -5,6 +5,46 @@
LOGGED_IN_USER=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')
# functions
+quit_application() {
+ local bundle_id="$1"
+ local timeout_duration=10
+
+ # check if the application is running
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Quitting application '$bundle_id'..."
+
+ # try to quit the application within the timeout period
+ local quit_success=false
+ SECONDS=0
+ while (( SECONDS < timeout_duration )); do
+ if osascript -e "tell application id \"$bundle_id\" to quit" >/dev/null 2>&1; then
+ if ! pgrep -f "$bundle_id" >/dev/null 2>&1; then
+ echo "Application '$bundle_id' quit successfully."
+ quit_success=true
+ break
+ fi
+ fi
+ sleep 1
+ done
+
+ if [[ "$quit_success" = false ]]; then
+ echo "Application '$bundle_id' did not quit."
+ fi
+}
+
+
trash() {
local logged_in_user="$1"
local target_file="$2"
@@ -52,9 +92,14 @@
fi
}
+quit_application 'com.TechSmith.Snagit'
sudo rm -rf "$APPDIR/Snagit.app"
+trash $LOGGED_IN_USER '~/Library/Application Scripts/7TQL462TU8.com.techsmith.snagit'
+trash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.techsmith.snagit.sfl*'
+trash $LOGGED_IN_USER '~/Library/Application Support/Snagit'
trash $LOGGED_IN_USER '~/Library/Caches/com.TechSmith.Snagit*'
trash $LOGGED_IN_USER '~/Library/Group Containers/*.com.techsmith.snagit'
+trash $LOGGED_IN_USER '~/Library/HTTPStorages/com.TechSmith.Snagit*'
trash $LOGGED_IN_USER '~/Library/Preferences/com.TechSmith.Snagit*.plist'
trash $LOGGED_IN_USER '~/Library/Preferences/com.techsmith.snagit.capturehelper*.plist'
trash $LOGGED_IN_USER '~/Library/Saved Application State/com.TechSmith.Snagit*.savedState'ee/maintained-apps/outputs/sourcetree/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/superwhisper/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/tabby/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/trezor-suite/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/visual-studio-code/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/vivaldi/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/wechat/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/whatsapp/darwin.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/workflowy/darwin.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) === |
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/onlyoffice/darwin.json`:
- Line 20: Update the embedded installer script to enable strict error handling
with set -euo pipefail, and add an EXIT trap after MOUNT_POINT is initialized to
detach the mount and remove the temporary directory. Make extraction commands,
especially cp and hdiutil attach, propagate failures instead of continuing;
remove the ignored detach error and ensure cleanup occurs before any backup or
installation steps run.
🪄 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 Plus
Run ID: 3a8f2bcd-fb0e-42bd-89ec-4dccc2ff53fa
📒 Files selected for processing (3)
ee/maintained-apps/inputs/homebrew/onlyoffice.jsonee/maintained-apps/inputs/winget/typora.jsonee/maintained-apps/outputs/onlyoffice/darwin.json
| "refs": { | ||
| "1f5bdb95": "#!/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/ONLYOFFICE.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/asc.onlyoffice.ONLYOFFICE'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/asc.onlyoffice.onlyoffice.sfl*'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/asc.onlyoffice.ONLYOFFICE'\ntrash $LOGGED_IN_USER '~/Library/Preferences/asc.onlyoffice.editors-helper-renderer.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/asc.onlyoffice.ONLYOFFICE.plist'\n", | ||
| "5beeff19": "#!/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\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'asc.onlyoffice.editors-helper-renderer'\nif [ -d \"$APPDIR/ONLYOFFICE.app\" ]; then\n\tsudo mv \"$APPDIR/ONLYOFFICE.app\" \"$TMPDIR/ONLYOFFICE.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/ONLYOFFICE.app\" \"$APPDIR\"\nrelaunch_application 'asc.onlyoffice.editors-helper-renderer'\n" | ||
| "e2c9162f": "#!/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 'asc.onlyoffice.editors-helper-renderer'\nif [ -d \"$APPDIR/ONLYOFFICE.app\" ]; then\n\tsudo mv \"$APPDIR/ONLYOFFICE.app\" \"$TMPDIR/ONLYOFFICE.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/ONLYOFFICE.app\" \"$APPDIR\"\nrelaunch_application 'asc.onlyoffice.editors-helper-renderer'\n" |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
rg -n 'set -e|pipefail|trap|cp -R|hdiutil detach' ee/maintained-apps/outputs/onlyoffice/darwin.jsonRepository: fleetdm/fleet
Length of output: 3941
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== File context =="
wc -l ee/maintained-apps/outputs/onlyoffice/darwin.json
sed -n '1,80p' ee/maintained-apps/outputs/onlyoffice/darwin.json | cat -n
echo "== Installer JSON schema context (around this file) =="
fd -a 'darwin\.json$' ee/maintained-apps/outputs 2>/dev/null | head -30
python3 - <<'PY'
import json, pathlib
p=pathlib.Path('ee/maintained-apps/outputs/onlyoffice/darwin.json')
data=json.loads(p.read_text())
print(type(data).__name__)
if isinstance(data, dict):
for k in sorted(data):
v=data[k]
if isinstance(v, dict):
print(k, {kk:v.get(kk) for kk in v if kk != 'install_script'})
else:
print(k, v[:240] if isinstance(v, str) else v)
PY
echo "== Shell behavior probe: pipeline status after yes + command that fails =="
# Demonstrate that `yes | hdiutil ... || exit 1` reports the final pipeline status
# in POSIX shell and that subsequent commands would still run only if that command succeeds.
sh -c 'yes | sh -c "exit 42" || echo "pipeline_failed"; echo "pipeline_status=$?"; next'
sh -c 'set -e; yes | sh -c "exit 42"; echo "continues_unless_pipefail"; set +e'
echo "== Simulate current script failure points without repository execution =="
python3 - <<'PY'
# Read-only behavioral model of the relevant shell command structure.
# Current pipeline: yes | hdiutil attach ... || exit 1
# The `||` only checks the pipeline exit status; if this succeeded, later commands run.
# Current cleanup: hdiutil detach || true means detach failures are ignored.
cases = [
("cp_after_attach_fails", {"attach_ok": True, "cp": 1, "detach_ok": True}),
("detach_fails", {"attach_ok": True, "cp": 0, "detach_ok": False}),
]
for name, k in cases:
attach_ok = k["attach_ok"]
detach_ok = k["detach_ok"]
first_failed = not attach_ok
# The script only proceeds if the first command exits 0.
proceeds_to_install = attach_ok
detach_ignored = True # current `|| true`
print(f"{name}: attach_ok={attach_ok}, cp_ok={k['cp']==0}, detach_ok={detach_ok}")
print(f" proceeds_to_install={proceeds_to_install}, detach_ignored={detach_ignored}")
PYRepository: fleetdm/fleet
Length of output: 16172
Propagate extraction failures and clean up the mount point.
sudo cp -R "$MOUNT_POINT"/* \"$TMPDIR\" can fail and is followed by relaunch/install steps, and hdiutil detach ignores errors with || true. Add set -euo pipefail, an EXIT trap to unmount/remove MOUNT_POINT, and explicit failures before backing up the installed app.
🤖 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/onlyoffice/darwin.json` at line 20, Update the
embedded installer script to enable strict error handling with set -euo
pipefail, and add an EXIT trap after MOUNT_POINT is initialized to detach the
mount and remove the temporary directory. Make extraction commands, especially
cp and hdiutil attach, propagate failures instead of continuing; remove the
ignored detach error and ensure cleanup occurs before any backup or installation
steps run.
|
Closing in favor of #49835. |
Script Diff Resultsee/maintained-apps/outputs/advanced-installer/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/akiflow/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/amie/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/anytype/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/aptakube/windows.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-sam-cli/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/bettertouchtool/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/betterzip/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/beyond-compare/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/brave-browser/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/brave-browser/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/burp-suite/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cleanmymac/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/clop/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/comet/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cursor/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dataflare/darwin.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/datagrip/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/datagrip/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dockside/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/drawio/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/enpass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/fellow/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/fellow/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===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/firefox@nightly/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/firefox@nightly/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/google-ads-editor/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/google-gemini/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/granola/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/granola/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/groove-omnidialer/darwin.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/hwmonitor/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/kiro-cli/darwin.json=== Install Script (no changes) ===
=== Uninstall // 31b59062 -> ed98f0de ===
--- /tmp/old.CDMgF9 2026-07-23 17:34:51.797608917 +0000
+++ /tmp/new.2OtkjA 2026-07-23 17:34:51.797608917 +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,10 +122,14 @@
fi
}
+remove_launchctl_service 'com.amazon.codewhisperer.launcher'
sudo rm -rf "$APPDIR/Kiro CLI.app"
trash $LOGGED_IN_USER '~/.kiro'
trash $LOGGED_IN_USER '~/.local/bin/kiro-cli'
trash $LOGGED_IN_USER '~/.local/bin/kiro-cli-chat'
trash $LOGGED_IN_USER '~/Library/Application Support/kiro-cli'
+trash $LOGGED_IN_USER '~/Library/Caches/com.amazon.codewhisperer'
trash $LOGGED_IN_USER '~/Library/Caches/dev.kiro.cli'
+trash $LOGGED_IN_USER '~/Library/LaunchAgents/com.amazon.codewhisperer.launcher.plist'
trash $LOGGED_IN_USER '~/Library/Preferences/dev.kiro.cli.plist'
+trash $LOGGED_IN_USER '~/Library/WebKit/com.amazon.codewhisperer'ee/maintained-apps/outputs/kiro/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/kiro/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/lookaway/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/macwhisper/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/marsedit/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/melodics/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/microsoft-teams/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/microsoft-teams/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/mozilla-vpn/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/mozilla-vpn/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/naps2/darwin.json=== Install // 54ba1114 -> 27c40399 ===
--- /tmp/old.1w9mIU 2026-07-23 17:34:52.368611310 +0000
+++ /tmp/new.aiMaem 2026-07-23 17:34:52.368611310 +0000
@@ -96,5 +96,5 @@
# install pkg files
quit_and_track_application 'com.naps2.desktop'
-sudo installer -pkg "$TMPDIR/naps2-8.3.1-mac-arm64.pkg" -target /
+sudo installer -pkg "$TMPDIR/naps2-8.3.2-mac-arm64.pkg" -target /
relaunch_application 'com.naps2.desktop'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/naps2/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nosql-workbench/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nosql-workbench/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/notepadexe/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/obs/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/only-switch/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/onlyoffice/darwin.json=== Install // 5beeff19 -> e2c9162f ===
--- /tmp/old.JK4d1I 2026-07-23 17:34:52.678612610 +0000
+++ /tmp/new.332JjH 2026-07-23 17:34:52.678612610 +0000
@@ -95,7 +95,10 @@
# extract contents
-unzip "$INSTALLER_PATH" -d "$TMPDIR"
+MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
+yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
+sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
+hdiutil detach "$MOUNT_POINT" || true
# copy to the applications folder
quit_and_track_application 'asc.onlyoffice.editors-helper-renderer'
if [ -d "$APPDIR/ONLYOFFICE.app" ]; then
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/picview/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/popclip/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/powerphotos/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/powershell/windows.json=== Install Script (no changes) ===
=== Uninstall // 0995d374 -> 06cf76b8 ===
--- /tmp/old.M7MRTL 2026-07-23 17:34:52.867613402 +0000
+++ /tmp/new.5vx44d 2026-07-23 17:34:52.867613402 +0000
@@ -1,4 +1,4 @@
-$product_code = '{7B031DCF-BDCE-47D6-89B9-4C558D76E773}'
+$product_code = '{92D9A5DC-8C64-40D5-B1BC-98DB9C7FDB7F}'
$timeoutSeconds = 300 # 5 minute timeout
# Fleet uninstalls app using product code that's extracted on uploadee/maintained-apps/outputs/prisma-browser/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/pritunl/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rider/darwin.json=== Install Script (no changes) ===
=== Uninstall // c52dae57 -> 22db20ac ===
--- /tmp/old.DXI21k 2026-07-23 17:34:52.995613939 +0000
+++ /tmp/new.DSNdUx 2026-07-23 17:34:52.995613939 +0000
@@ -54,9 +54,9 @@
sudo rm -rf "$APPDIR/Rider.app"
sudo rm -rf 'rider'
-trash $LOGGED_IN_USER '~/Library/Application Support/Rider2026.1'
-trash $LOGGED_IN_USER '~/Library/Caches/Rider2026.1'
-trash $LOGGED_IN_USER '~/Library/Logs/Rider2026.1'
+trash $LOGGED_IN_USER '~/Library/Application Support/Rider2026.2'
+trash $LOGGED_IN_USER '~/Library/Caches/Rider2026.2'
+trash $LOGGED_IN_USER '~/Library/Logs/Rider2026.2'
trash $LOGGED_IN_USER '~/Library/Preferences/jetbrains.rider.71e559ef.plist'
-trash $LOGGED_IN_USER '~/Library/Preferences/Rider2026.1'
+trash $LOGGED_IN_USER '~/Library/Preferences/Rider2026.2'
trash $LOGGED_IN_USER '~/Library/Saved Application State/com.jetbrains.rider.savedState'ee/maintained-apps/outputs/rive/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rustrover/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/setapp/darwin.json=== Install Script (no changes) ===
=== Uninstall // e23bd29d -> 9ef05eb6 ===
--- /tmp/old.3iJ2D2 2026-07-23 17:34:53.125614484 +0000
+++ /tmp/new.3EuB4Y 2026-07-23 17:34:53.126614488 +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,10 +122,19 @@
fi
}
+remove_launchctl_service 'com.setapp.DesktopClient.SetappAgent'
+remove_launchctl_service 'com.setapp.DesktopClient.SetappAssistant'
+remove_launchctl_service 'com.setapp.DesktopClient.SetappLauncher'
+remove_launchctl_service 'com.setapp.DesktopClient.SetappUpdater'
sudo rm -rf "$APPDIR/Setapp.app"
trash $LOGGED_IN_USER '~/Library/Application Scripts/com.setapp.DesktopClient.SetappAgent.FinderSyncExt'
+trash $LOGGED_IN_USER '~/Library/Application Support/Setapp*'
trash $LOGGED_IN_USER '~/Library/Caches/com.setapp.DesktopClient'
trash $LOGGED_IN_USER '~/Library/Caches/com.setapp.DesktopClient.SetappAgent'
+trash $LOGGED_IN_USER '~/Library/Containers/com.setapp.DesktopClient.SetappAgent.FinderSyncExt'
+trash $LOGGED_IN_USER '~/Library/HTTPStorages/com.setapp.DesktopClient*'
+trash $LOGGED_IN_USER '~/Library/LaunchAgents/com.setapp.DesktopClient.*plist'
trash $LOGGED_IN_USER '~/Library/Logs/Setapp'
+trash $LOGGED_IN_USER '~/Library/Preferences/com.setapp.DesktopClient.plist'
trash $LOGGED_IN_USER '~/Library/Preferences/com.setapp.DesktopClient.SetappAgent.plist'
trash $LOGGED_IN_USER '~/Library/Saved Application State/com.setapp.DesktopClient.savedState'ee/maintained-apps/outputs/sidenotes/darwin.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/snagit/darwin.json=== Install Script (no changes) ===
=== Uninstall // b52ff2b2 -> 59bfdeae ===
--- /tmp/old.xb4k64 2026-07-23 17:34:53.303615230 +0000
+++ /tmp/new.M487Jc 2026-07-23 17:34:53.303615230 +0000
@@ -5,6 +5,46 @@
LOGGED_IN_USER=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')
# functions
+quit_application() {
+ local bundle_id="$1"
+ local timeout_duration=10
+
+ # check if the application is running
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Quitting application '$bundle_id'..."
+
+ # try to quit the application within the timeout period
+ local quit_success=false
+ SECONDS=0
+ while (( SECONDS < timeout_duration )); do
+ if osascript -e "tell application id \"$bundle_id\" to quit" >/dev/null 2>&1; then
+ if ! pgrep -f "$bundle_id" >/dev/null 2>&1; then
+ echo "Application '$bundle_id' quit successfully."
+ quit_success=true
+ break
+ fi
+ fi
+ sleep 1
+ done
+
+ if [[ "$quit_success" = false ]]; then
+ echo "Application '$bundle_id' did not quit."
+ fi
+}
+
+
trash() {
local logged_in_user="$1"
local target_file="$2"
@@ -52,9 +92,14 @@
fi
}
+quit_application 'com.TechSmith.Snagit'
sudo rm -rf "$APPDIR/Snagit.app"
+trash $LOGGED_IN_USER '~/Library/Application Scripts/7TQL462TU8.com.techsmith.snagit'
+trash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.techsmith.snagit.sfl*'
+trash $LOGGED_IN_USER '~/Library/Application Support/Snagit'
trash $LOGGED_IN_USER '~/Library/Caches/com.TechSmith.Snagit*'
trash $LOGGED_IN_USER '~/Library/Group Containers/*.com.techsmith.snagit'
+trash $LOGGED_IN_USER '~/Library/HTTPStorages/com.TechSmith.Snagit*'
trash $LOGGED_IN_USER '~/Library/Preferences/com.TechSmith.Snagit*.plist'
trash $LOGGED_IN_USER '~/Library/Preferences/com.techsmith.snagit.capturehelper*.plist'
trash $LOGGED_IN_USER '~/Library/Saved Application State/com.TechSmith.Snagit*.savedState'ee/maintained-apps/outputs/sourcetree/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/superwhisper/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/tabby/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/trezor-suite/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/visual-studio-code/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/vivaldi/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/wechat/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/whatsapp/darwin.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/workflowy/darwin.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) === |
The MSI starts the MozillaVPNBroker/MozillaVPNProxy services (Wait=1) and auto-launches the Mozilla VPN GUI as an async custom action on a fresh install. The default 'Start-Process msiexec -Wait' waits on the whole process tree, so the validate step never returned and the shard died after ~1h. Add a custom install_script_path that launches msiexec without -Wait, polls the msiexec process itself (not descendants) with a 300s timeout, then stops the lingering GUI so it can't affect later apps in the run. Uninstall is unchanged (default bounded MSI uninstall).
Script Diff Resultsee/maintained-apps/outputs/advanced-installer/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/akiflow/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/amie/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/anytype/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/aptakube/windows.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-sam-cli/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/bettertouchtool/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/betterzip/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/beyond-compare/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/brave-browser/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/brave-browser/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/burp-suite/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cleanmymac/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/clop/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/comet/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cursor/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dataflare/darwin.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/datagrip/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/datagrip/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dockside/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/drawio/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/enpass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/fellow/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/fellow/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===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/firefox@nightly/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/firefox@nightly/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/google-ads-editor/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/google-gemini/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/granola/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/granola/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/groove-omnidialer/darwin.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/hwmonitor/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/kiro-cli/darwin.json=== Install Script (no changes) ===
=== Uninstall // 31b59062 -> ed98f0de ===
--- /tmp/old.mkJwBQ 2026-07-23 18:27:28.331845308 +0000
+++ /tmp/new.5kcZdC 2026-07-23 18:27:28.332845310 +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,10 +122,14 @@
fi
}
+remove_launchctl_service 'com.amazon.codewhisperer.launcher'
sudo rm -rf "$APPDIR/Kiro CLI.app"
trash $LOGGED_IN_USER '~/.kiro'
trash $LOGGED_IN_USER '~/.local/bin/kiro-cli'
trash $LOGGED_IN_USER '~/.local/bin/kiro-cli-chat'
trash $LOGGED_IN_USER '~/Library/Application Support/kiro-cli'
+trash $LOGGED_IN_USER '~/Library/Caches/com.amazon.codewhisperer'
trash $LOGGED_IN_USER '~/Library/Caches/dev.kiro.cli'
+trash $LOGGED_IN_USER '~/Library/LaunchAgents/com.amazon.codewhisperer.launcher.plist'
trash $LOGGED_IN_USER '~/Library/Preferences/dev.kiro.cli.plist'
+trash $LOGGED_IN_USER '~/Library/WebKit/com.amazon.codewhisperer'ee/maintained-apps/outputs/kiro/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/kiro/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/lookaway/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/macwhisper/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/marsedit/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/melodics/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/microsoft-teams/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/microsoft-teams/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/mozilla-vpn/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/mozilla-vpn/windows.json=== Install // 8959087b -> c02fc638 ===
--- /tmp/old.oY91h7 2026-07-23 18:27:28.819846402 +0000
+++ /tmp/new.ztyhDn 2026-07-23 18:27:28.819846402 +0000
@@ -1,16 +1,77 @@
+# Learn more about .msi install scripts:
+# http://fleetdm.com/learn-more-about/msi-install-scripts
+#
+# Mozilla VPN's MSI starts the MozillaVPNBroker / MozillaVPNProxy services
+# (ServiceControl with Wait=1) and, on a fresh install, auto-launches the
+# "Mozilla VPN" GUI via an async custom action. On a headless CI host those
+# processes linger, and the default "Start-Process msiexec -Wait" waits on the
+# whole process tree -- so the step never returns even though the product
+# installs correctly, and the runner is eventually killed (~1h). Instead we
+# wait on the msiexec process ITSELF (not its descendants) with a bounded
+# timeout, then stop any lingering Mozilla VPN GUI process so it can't
+# interfere with the rest of the validation run.
+
$logFile = "${env:TEMP}/fleet-install-software.log"
+$msiFilePath = "${env:INSTALLER_PATH}"
+
+$timeoutSeconds = 300
+$pollIntervalSeconds = 5
+
+# Recursively stop a process and its children (used only if msiexec wedges).
+function Stop-ProcessTree {
+ param([int]$ParentId)
+ Get-CimInstance Win32_Process -Filter "ParentProcessId = $ParentId" -ErrorAction SilentlyContinue |
+ ForEach-Object { Stop-ProcessTree -ParentId $_.ProcessId }
+ Stop-Process -Id $ParentId -Force -ErrorAction SilentlyContinue
+}
try {
+ if (-not (Test-Path $msiFilePath)) {
+ Write-Host "Error: Installer file not found at: $msiFilePath"
+ Exit 1
+ }
+
+ $processOptions = @{
+ FilePath = "msiexec.exe"
+ ArgumentList = "/i `"$msiFilePath`" /quiet /norestart /lv `"$logFile`""
+ PassThru = $true
+ }
+
+ # NOTE: intentionally launched WITHOUT -Wait; -Wait would block on the
+ # auto-launched app / services that outlive the install.
+ $process = Start-Process @processOptions
+ Write-Host "Launched Mozilla VPN MSI (PID: $($process.Id))"
+
+ $elapsed = 0
+ while (-not $process.HasExited -and $elapsed -lt $timeoutSeconds) {
+ Start-Sleep -Seconds $pollIntervalSeconds
+ $elapsed += $pollIntervalSeconds
+ }
+
+ if (-not $process.HasExited) {
+ Write-Host "msiexec did not complete within ${timeoutSeconds}s; stopping it."
+ Stop-ProcessTree -ParentId $process.Id
+ Get-Content $logFile -Tail 500 -ErrorAction SilentlyContinue
+ Exit 1
+ }
+
+ $exitCode = $process.ExitCode
+ Write-Host "Install exit code: $exitCode"
+
+ # Stop the auto-launched GUI so it doesn't linger into later apps in the run.
+ # (This only ends the running process; it does not uninstall anything.)
+ Stop-Process -Name "Mozilla VPN", "MozillaVPN" -Force -ErrorAction SilentlyContinue
-$installProcess = Start-Process msiexec.exe `
- -ArgumentList "/quiet /norestart /lv ${logFile} /i `"${env:INSTALLER_PATH}`"" `
- -PassThru -Verb RunAs -Wait
+ # MSI reboot-required success codes.
+ if ($exitCode -eq 3010 -or $exitCode -eq 1641) { Exit 0 }
-Get-Content $logFile -Tail 500
+ if ($exitCode -ne 0) {
+ Get-Content $logFile -Tail 500
+ }
-Exit $installProcess.ExitCode
+ Exit $exitCode
} catch {
- Write-Host "Error: $_"
- Exit 1
+ Write-Host "Error: $_"
+ Exit 1
}
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/naps2/darwin.json=== Install // 54ba1114 -> 27c40399 ===
--- /tmp/old.tRPTxF 2026-07-23 18:27:28.867846509 +0000
+++ /tmp/new.FQijeU 2026-07-23 18:27:28.867846509 +0000
@@ -96,5 +96,5 @@
# install pkg files
quit_and_track_application 'com.naps2.desktop'
-sudo installer -pkg "$TMPDIR/naps2-8.3.1-mac-arm64.pkg" -target /
+sudo installer -pkg "$TMPDIR/naps2-8.3.2-mac-arm64.pkg" -target /
relaunch_application 'com.naps2.desktop'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/naps2/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nosql-workbench/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nosql-workbench/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/notepadexe/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/obs/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/only-switch/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/onlyoffice/darwin.json=== Install // 5beeff19 -> e2c9162f ===
--- /tmp/old.3lfbAF 2026-07-23 18:27:29.160847166 +0000
+++ /tmp/new.gDsPY5 2026-07-23 18:27:29.160847166 +0000
@@ -95,7 +95,10 @@
# extract contents
-unzip "$INSTALLER_PATH" -d "$TMPDIR"
+MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
+yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
+sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
+hdiutil detach "$MOUNT_POINT" || true
# copy to the applications folder
quit_and_track_application 'asc.onlyoffice.editors-helper-renderer'
if [ -d "$APPDIR/ONLYOFFICE.app" ]; then
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/picview/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/popclip/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/powerphotos/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/powershell/windows.json=== Install Script (no changes) ===
=== Uninstall // 0995d374 -> 06cf76b8 ===
--- /tmp/old.0PlRlb 2026-07-23 18:27:29.342847574 +0000
+++ /tmp/new.9ju3VX 2026-07-23 18:27:29.342847574 +0000
@@ -1,4 +1,4 @@
-$product_code = '{7B031DCF-BDCE-47D6-89B9-4C558D76E773}'
+$product_code = '{92D9A5DC-8C64-40D5-B1BC-98DB9C7FDB7F}'
$timeoutSeconds = 300 # 5 minute timeout
# Fleet uninstalls app using product code that's extracted on uploadee/maintained-apps/outputs/prisma-browser/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/pritunl/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rider/darwin.json=== Install Script (no changes) ===
=== Uninstall // c52dae57 -> 22db20ac ===
--- /tmp/old.INhLaV 2026-07-23 18:27:29.464847848 +0000
+++ /tmp/new.7pQLwq 2026-07-23 18:27:29.465847850 +0000
@@ -54,9 +54,9 @@
sudo rm -rf "$APPDIR/Rider.app"
sudo rm -rf 'rider'
-trash $LOGGED_IN_USER '~/Library/Application Support/Rider2026.1'
-trash $LOGGED_IN_USER '~/Library/Caches/Rider2026.1'
-trash $LOGGED_IN_USER '~/Library/Logs/Rider2026.1'
+trash $LOGGED_IN_USER '~/Library/Application Support/Rider2026.2'
+trash $LOGGED_IN_USER '~/Library/Caches/Rider2026.2'
+trash $LOGGED_IN_USER '~/Library/Logs/Rider2026.2'
trash $LOGGED_IN_USER '~/Library/Preferences/jetbrains.rider.71e559ef.plist'
-trash $LOGGED_IN_USER '~/Library/Preferences/Rider2026.1'
+trash $LOGGED_IN_USER '~/Library/Preferences/Rider2026.2'
trash $LOGGED_IN_USER '~/Library/Saved Application State/com.jetbrains.rider.savedState'ee/maintained-apps/outputs/rive/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rustrover/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/setapp/darwin.json=== Install Script (no changes) ===
=== Uninstall // e23bd29d -> 9ef05eb6 ===
--- /tmp/old.YWlzm7 2026-07-23 18:27:29.586848121 +0000
+++ /tmp/new.iniPso 2026-07-23 18:27:29.587848124 +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,10 +122,19 @@
fi
}
+remove_launchctl_service 'com.setapp.DesktopClient.SetappAgent'
+remove_launchctl_service 'com.setapp.DesktopClient.SetappAssistant'
+remove_launchctl_service 'com.setapp.DesktopClient.SetappLauncher'
+remove_launchctl_service 'com.setapp.DesktopClient.SetappUpdater'
sudo rm -rf "$APPDIR/Setapp.app"
trash $LOGGED_IN_USER '~/Library/Application Scripts/com.setapp.DesktopClient.SetappAgent.FinderSyncExt'
+trash $LOGGED_IN_USER '~/Library/Application Support/Setapp*'
trash $LOGGED_IN_USER '~/Library/Caches/com.setapp.DesktopClient'
trash $LOGGED_IN_USER '~/Library/Caches/com.setapp.DesktopClient.SetappAgent'
+trash $LOGGED_IN_USER '~/Library/Containers/com.setapp.DesktopClient.SetappAgent.FinderSyncExt'
+trash $LOGGED_IN_USER '~/Library/HTTPStorages/com.setapp.DesktopClient*'
+trash $LOGGED_IN_USER '~/Library/LaunchAgents/com.setapp.DesktopClient.*plist'
trash $LOGGED_IN_USER '~/Library/Logs/Setapp'
+trash $LOGGED_IN_USER '~/Library/Preferences/com.setapp.DesktopClient.plist'
trash $LOGGED_IN_USER '~/Library/Preferences/com.setapp.DesktopClient.SetappAgent.plist'
trash $LOGGED_IN_USER '~/Library/Saved Application State/com.setapp.DesktopClient.savedState'ee/maintained-apps/outputs/sidenotes/darwin.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/snagit/darwin.json=== Install Script (no changes) ===
=== Uninstall // b52ff2b2 -> 59bfdeae ===
--- /tmp/old.cRCzCH 2026-07-23 18:27:29.750848489 +0000
+++ /tmp/new.XtySid 2026-07-23 18:27:29.751848491 +0000
@@ -5,6 +5,46 @@
LOGGED_IN_USER=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')
# functions
+quit_application() {
+ local bundle_id="$1"
+ local timeout_duration=10
+
+ # check if the application is running
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Quitting application '$bundle_id'..."
+
+ # try to quit the application within the timeout period
+ local quit_success=false
+ SECONDS=0
+ while (( SECONDS < timeout_duration )); do
+ if osascript -e "tell application id \"$bundle_id\" to quit" >/dev/null 2>&1; then
+ if ! pgrep -f "$bundle_id" >/dev/null 2>&1; then
+ echo "Application '$bundle_id' quit successfully."
+ quit_success=true
+ break
+ fi
+ fi
+ sleep 1
+ done
+
+ if [[ "$quit_success" = false ]]; then
+ echo "Application '$bundle_id' did not quit."
+ fi
+}
+
+
trash() {
local logged_in_user="$1"
local target_file="$2"
@@ -52,9 +92,14 @@
fi
}
+quit_application 'com.TechSmith.Snagit'
sudo rm -rf "$APPDIR/Snagit.app"
+trash $LOGGED_IN_USER '~/Library/Application Scripts/7TQL462TU8.com.techsmith.snagit'
+trash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.techsmith.snagit.sfl*'
+trash $LOGGED_IN_USER '~/Library/Application Support/Snagit'
trash $LOGGED_IN_USER '~/Library/Caches/com.TechSmith.Snagit*'
trash $LOGGED_IN_USER '~/Library/Group Containers/*.com.techsmith.snagit'
+trash $LOGGED_IN_USER '~/Library/HTTPStorages/com.TechSmith.Snagit*'
trash $LOGGED_IN_USER '~/Library/Preferences/com.TechSmith.Snagit*.plist'
trash $LOGGED_IN_USER '~/Library/Preferences/com.techsmith.snagit.capturehelper*.plist'
trash $LOGGED_IN_USER '~/Library/Saved Application State/com.TechSmith.Snagit*.savedState'ee/maintained-apps/outputs/sourcetree/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/superwhisper/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/tabby/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/trezor-suite/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/visual-studio-code/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/vivaldi/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/wechat/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/whatsapp/darwin.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/workflowy/darwin.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) === |
- pritunl/windows: revert 1.3.4696.56 -> 1.3.4686.95 (the installer registers as 1.3.4686.95, so 1.3.4696.56 is never found by osquery) - pritunl/darwin: revert the re-bump to 1.3.4696.56 (same issue as the earlier revert in #49813: the bundle still reports 1.3.4686.95) - freeze winget + homebrew inputs so the bot stops re-bumping until upstream ships a release that reports its own version
Automated ingestion of latest Fleet-maintained app data.
Summary by CodeRabbit