Update scripts in Fleet-maintained apps - #50756
Conversation
Generated automatically with cmd/maintained-apps.
Script Diff Resultsee/maintained-apps/outputs/alt-tab/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/amadine/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/arc/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/badgeify/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/beekeeper-studio/windows.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/calibre/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/calibre/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/capcut/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/chatbox/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/chatgpt/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cherry-studio/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/claude/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cmake-app/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/codexbar/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/coteditor/darwin.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/deezer/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/downie/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/drofus/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/elevate-uc/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/evernote/windows.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/firefox@nightly/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/framer/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/gitkraken/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/gog-galaxy/darwin.json=== Install // 9f170824 -> 89b9a1b7 ===
--- /tmp/old.cCgrw4 2026-08-07 12:21:09.699637610 +0000
+++ /tmp/new.iJvC86 2026-08-07 12:21:09.700637611 +0000
@@ -96,5 +96,5 @@
# install pkg files
quit_and_track_application 'com.gog.galaxy.cef.renderer'
-sudo installer -pkg "$TMPDIR/galaxy_client_2.1.7.22.pkg" -target / || exit $?
+sudo installer -pkg "$TMPDIR/galaxy_client_2.1.8.32.pkg" -target / || exit $?
relaunch_application 'com.gog.galaxy.cef.renderer'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/google-chrome/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/ibm-semeru-jre-11/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/imageglass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/kiro-cli/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===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/krita/darwin.json=== Install Script (no changes) ===
=== Uninstall // 7b9f27dc -> 3947b0f0 ===
--- /tmp/old.WUlHsB 2026-08-07 12:21:09.999637953 +0000
+++ /tmp/new.A044WB 2026-08-07 12:21:09.999637953 +0000
@@ -52,8 +52,11 @@
fi
}
-sudo rm -rf "$APPDIR/krita.app"
-trash $LOGGED_IN_USER '~/Library/Application Support/krita'
+sudo rm -rf "$APPDIR/Krita.app"
+trash $LOGGED_IN_USER '~/Library/Application Scripts/org.krita.*'
+trash $LOGGED_IN_USER '~/Library/Application Support/krita*'
+trash $LOGGED_IN_USER '~/Library/Caches/krita'
+trash $LOGGED_IN_USER '~/Library/Containers/org.krita.*'
trash $LOGGED_IN_USER '~/Library/Preferences/kritadisplayrc'
trash $LOGGED_IN_USER '~/Library/Preferences/kritarc'
trash $LOGGED_IN_USER '~/Library/Saved Application State/org.krita.savedState'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/marked-app/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/masscode/darwin.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-edge/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/mongodb-compass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nordpass/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nordpass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/notesnook/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nova/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/onedrive/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/opencode-desktop/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/opera/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/orbstack/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/p4v/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/p4v/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/pale-moon/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/parallels/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/postman/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/postman/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/powerphotos/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/prisma-browser/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/prisma-browser/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/proton-drive/darwin.json=== Install Script (no changes) ===
=== Uninstall // fc6f5099 -> ac89ef74 ===
--- /tmp/old.IRHEhM 2026-08-07 12:21:10.940639027 +0000
+++ /tmp/new.HVsy9Q 2026-08-07 12:21:10.940639027 +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,6 +122,7 @@
fi
}
+remove_launchctl_service 'ch.protonmail.drive.agent'
sudo rm -rf "$APPDIR/Proton Drive.app"
trash $LOGGED_IN_USER '~/Library/Application Scripts/ch.protonmail.drive*'
trash $LOGGED_IN_USER '~/Library/Application Support/FileProvider/ch.protonmail.drive.fileprovider'ee/maintained-apps/outputs/rider/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rive/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rustrover/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/shapr3d/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/spokenly/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/spotify/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/spyder/windows.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/sync/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/telegram/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/viscosity/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/viscosity/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/webex/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/windows-app/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/wispr-flow/darwin.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/xnconvert/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/zen/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) === |
WalkthroughUpdated maintained application metadata for Darwin and Windows applications. Changes include release versions, patch-detection queries, installer URLs, and SHA-256 checksums. Selected entries update installer or uninstaller script references. Krita and Proton Drive update cleanup behavior. Evernote verifies registry removal after uninstall. Webex is marked as frozen. Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ 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: 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/krita/darwin.json`:
- Line 19: Update the uninstall command in the script identified by the sudo rm
invocation to remove “$APPDIR/krita.app” with the same lowercase casing used by
the installer, while leaving the surrounding trash cleanup unchanged.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 767ede1b-1063-4a37-9817-27c8aafd8d99
📒 Files selected for processing (84)
ee/maintained-apps/outputs/alt-tab/darwin.jsonee/maintained-apps/outputs/amadine/darwin.jsonee/maintained-apps/outputs/arc/darwin.jsonee/maintained-apps/outputs/badgeify/darwin.jsonee/maintained-apps/outputs/beekeeper-studio/windows.jsonee/maintained-apps/outputs/brave-browser/windows.jsonee/maintained-apps/outputs/burp-suite/darwin.jsonee/maintained-apps/outputs/calibre/darwin.jsonee/maintained-apps/outputs/calibre/windows.jsonee/maintained-apps/outputs/capcut/darwin.jsonee/maintained-apps/outputs/chatbox/windows.jsonee/maintained-apps/outputs/chatgpt/darwin.jsonee/maintained-apps/outputs/cherry-studio/darwin.jsonee/maintained-apps/outputs/claude/darwin.jsonee/maintained-apps/outputs/cmake-app/windows.jsonee/maintained-apps/outputs/codexbar/darwin.jsonee/maintained-apps/outputs/coteditor/darwin.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/deezer/darwin.jsonee/maintained-apps/outputs/downie/darwin.jsonee/maintained-apps/outputs/drofus/windows.jsonee/maintained-apps/outputs/elevate-uc/windows.jsonee/maintained-apps/outputs/evernote/windows.jsonee/maintained-apps/outputs/fellow/windows.jsonee/maintained-apps/outputs/firefox@nightly/darwin.jsonee/maintained-apps/outputs/framer/darwin.jsonee/maintained-apps/outputs/gitkraken/windows.jsonee/maintained-apps/outputs/gog-galaxy/darwin.jsonee/maintained-apps/outputs/google-chrome/darwin.jsonee/maintained-apps/outputs/granola/darwin.jsonee/maintained-apps/outputs/ibm-semeru-jre-11/windows.jsonee/maintained-apps/outputs/imageglass/windows.jsonee/maintained-apps/outputs/kiro-cli/darwin.jsonee/maintained-apps/outputs/kiro/darwin.jsonee/maintained-apps/outputs/kiro/windows.jsonee/maintained-apps/outputs/krita/darwin.jsonee/maintained-apps/outputs/loom/darwin.jsonee/maintained-apps/outputs/loom/windows.jsonee/maintained-apps/outputs/marked-app/darwin.jsonee/maintained-apps/outputs/masscode/darwin.jsonee/maintained-apps/outputs/melodics/darwin.jsonee/maintained-apps/outputs/microsoft-edge/darwin.jsonee/maintained-apps/outputs/mongodb-compass/windows.jsonee/maintained-apps/outputs/nordpass/darwin.jsonee/maintained-apps/outputs/nordpass/windows.jsonee/maintained-apps/outputs/notesnook/windows.jsonee/maintained-apps/outputs/nova/darwin.jsonee/maintained-apps/outputs/onedrive/windows.jsonee/maintained-apps/outputs/opencode-desktop/darwin.jsonee/maintained-apps/outputs/opera/darwin.jsonee/maintained-apps/outputs/orbstack/darwin.jsonee/maintained-apps/outputs/p4v/darwin.jsonee/maintained-apps/outputs/p4v/windows.jsonee/maintained-apps/outputs/pale-moon/windows.jsonee/maintained-apps/outputs/parallels/darwin.jsonee/maintained-apps/outputs/postman/darwin.jsonee/maintained-apps/outputs/postman/windows.jsonee/maintained-apps/outputs/powerphotos/darwin.jsonee/maintained-apps/outputs/prisma-browser/darwin.jsonee/maintained-apps/outputs/prisma-browser/windows.jsonee/maintained-apps/outputs/proton-drive/darwin.jsonee/maintained-apps/outputs/rider/windows.jsonee/maintained-apps/outputs/rive/darwin.jsonee/maintained-apps/outputs/rustrover/darwin.jsonee/maintained-apps/outputs/rustrover/windows.jsonee/maintained-apps/outputs/shapr3d/darwin.jsonee/maintained-apps/outputs/spokenly/darwin.jsonee/maintained-apps/outputs/spotify/darwin.jsonee/maintained-apps/outputs/spyder/windows.jsonee/maintained-apps/outputs/superwhisper/darwin.jsonee/maintained-apps/outputs/sync/darwin.jsonee/maintained-apps/outputs/telegram/windows.jsonee/maintained-apps/outputs/viscosity/darwin.jsonee/maintained-apps/outputs/viscosity/windows.jsonee/maintained-apps/outputs/webex/darwin.jsonee/maintained-apps/outputs/whatsapp/darwin.jsonee/maintained-apps/outputs/windows-app/windows.jsonee/maintained-apps/outputs/wispr-flow/darwin.jsonee/maintained-apps/outputs/workflowy/darwin.jsonee/maintained-apps/outputs/xnconvert/windows.jsonee/maintained-apps/outputs/zen/darwin.json
| ], | ||
| "refs": { | ||
| "7b9f27dc": "#!/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/krita.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/krita'\ntrash $LOGGED_IN_USER '~/Library/Preferences/kritadisplayrc'\ntrash $LOGGED_IN_USER '~/Library/Preferences/kritarc'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/org.krita.savedState'\n", | ||
| "3947b0f0": "#!/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/Krita.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/org.krita.*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/krita*'\ntrash $LOGGED_IN_USER '~/Library/Caches/krita'\ntrash $LOGGED_IN_USER '~/Library/Containers/org.krita.*'\ntrash $LOGGED_IN_USER '~/Library/Preferences/kritadisplayrc'\ntrash $LOGGED_IN_USER '~/Library/Preferences/kritarc'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/org.krita.savedState'\n", |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Use the installed bundle’s exact path casing.
Line 19 removes $APPDIR/Krita.app, but the cdb966e7 install script copies $TMPDIR/krita.app and removes $APPDIR/krita.app at Line 20. On a case-sensitive macOS volume, uninstall leaves the application bundle behind. Apple documents case-sensitive APFS variants. (developer.apple.com)
Use $APPDIR/krita.app in the uninstall script.
Proposed fix
- sudo rm -rf "$APPDIR/Krita.app"
+ sudo rm -rf "$APPDIR/krita.app"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "3947b0f0": "#!/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/Krita.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/org.krita.*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/krita*'\ntrash $LOGGED_IN_USER '~/Library/Caches/krita'\ntrash $LOGGED_IN_USER '~/Library/Containers/org.krita.*'\ntrash $LOGGED_IN_USER '~/Library/Preferences/kritadisplayrc'\ntrash $LOGGED_IN_USER '~/Library/Preferences/kritarc'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/org.krita.savedState'\n", | |
| "3947b0f0": "#!/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/krita.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/org.krita.*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/krita*'\ntrash $LOGGED_IN_USER '~/Library/Caches/krita'\ntrash $LOGGED_IN_USER '~/Library/Containers/org.krita.*'\ntrash $LOGGED_IN_USER '~/Library/Preferences/kritadisplayrc'\ntrash $LOGGED_IN_USER '~/Library/Preferences/kritarc'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/org.krita.savedState'\n", |
🤖 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/krita/darwin.json` at line 19, Update the
uninstall command in the script identified by the sudo rm invocation to remove
“$APPDIR/krita.app” with the same lowercase casing used by the installer, while
leaving the surrounding trash cleanup unchanged.
Webex (darwin): the 46.8.0 cask reports 46.8.0.33593, but the DMG it points at installs 46.8.0.35593, so the version check could never match. Revert the output to the last known good 46.7.0.35472 and freeze the input so the ingester stops republishing the bad version. XnSoft XnConvert (windows): XnView republished XnConvert-1.115.0-win-x64.exe at the same URL, so winget's manifest hash is stale. Verified the served file is still 1.115.0.0 and updated the hash. NordPass (windows): downloads.npass.app serves the latest build, and NordPass has shipped 7.9.4 while winget still lists 7.9.3. A new hash alone would have traded the hash mismatch for a version mismatch, so bump the version to 7.9.4 (matching the darwin output) along with the hash of the file being served. Evernote (windows): the uninstall reported success while the app was still registered. Its electron-builder NSIS uninstaller copies itself to %TEMP% and relaunches detached when no "_?=<installdir>" argument is given, so the process the script waits on exits 0 before the removal finishes. Wait for the uninstall registry entry to actually disappear before reporting success.
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/inputs/winget/scripts/evernote_uninstall.ps1`:
- Around line 84-88: The final registry query in evernote_uninstall.ps1 must
fail closed: add explicit error handling around the Get-ChildItem pipeline so
query failures cannot leave $stillInstalled empty and allow a successful exit
while Evernote remains registered. Regenerate the embedded a97ad90f script in
ee/maintained-apps/outputs/evernote/windows.json with the same behavior; both
affected sites require the equivalent update.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: d42472d6-8f91-420b-b81d-e8e2468dbd3f
📒 Files selected for processing (5)
ee/maintained-apps/inputs/homebrew/webex.jsonee/maintained-apps/inputs/winget/scripts/evernote_uninstall.ps1ee/maintained-apps/outputs/evernote/windows.jsonee/maintained-apps/outputs/nordpass/windows.jsonee/maintained-apps/outputs/xnconvert/windows.json
🚧 Files skipped from review as they are similar to previous changes (1)
- ee/maintained-apps/outputs/xnconvert/windows.json
Script Diff Resultsee/maintained-apps/outputs/alt-tab/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/amadine/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/arc/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/badgeify/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/beekeeper-studio/windows.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/calibre/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/calibre/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/capcut/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/chatbox/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/chatgpt/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cherry-studio/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/claude/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cmake-app/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/codexbar/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/coteditor/darwin.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/deezer/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/downie/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/drofus/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/elevate-uc/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/evernote/windows.json=== Install Script (no changes) ===
=== Uninstall // d4142835 -> a97ad90f ===
--- /tmp/old.kQkNsL 2026-08-07 15:53:20.658634482 +0000
+++ /tmp/new.tlP310 2026-08-07 15:53:20.658634482 +0000
@@ -71,6 +71,31 @@
# Prints the exit code
Write-Host "Uninstall exit code: $exitCode"
+
+ # Without an "_?=<installdir>" argument, an NSIS uninstaller copies
+ # itself to %TEMP%, relaunches the copy detached, and the process we
+ # waited on exits 0 immediately -- so the removal is still in flight
+ # here. Poll the uninstall registry key until the entry disappears so
+ # this script only reports success once the app is really gone.
+ if ($exitCode -eq 0) {
+ $deadline = (Get-Date).AddSeconds(300)
+ do {
+ Start-Sleep -Seconds 5
+ $stillInstalled = Get-ChildItem `
+ -Path @($machineKey, $machineKey32on64) `
+ -ErrorAction SilentlyContinue |
+ ForEach-Object { Get-ItemProperty $_.PSPath } |
+ Where-Object { $_.DisplayName -like $softwareNameLike }
+ } while ($stillInstalled -and (Get-Date) -lt $deadline)
+
+ if ($stillInstalled) {
+ Write-Host "'$softwareName' is still registered after waiting."
+ $exitCode = 1
+ } else {
+ Write-Host "'$softwareName' was removed."
+ }
+ }
+
# Exit the loop once the software is found and uninstalled.
break
}ee/maintained-apps/outputs/fellow/windows.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/framer/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/gitkraken/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/gog-galaxy/darwin.json=== Install // 9f170824 -> 89b9a1b7 ===
--- /tmp/old.7h5XvT 2026-08-07 15:53:20.874634185 +0000
+++ /tmp/new.GpT3wc 2026-08-07 15:53:20.874634185 +0000
@@ -96,5 +96,5 @@
# install pkg files
quit_and_track_application 'com.gog.galaxy.cef.renderer'
-sudo installer -pkg "$TMPDIR/galaxy_client_2.1.7.22.pkg" -target / || exit $?
+sudo installer -pkg "$TMPDIR/galaxy_client_2.1.8.32.pkg" -target / || exit $?
relaunch_application 'com.gog.galaxy.cef.renderer'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/google-chrome/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/ibm-semeru-jre-11/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/imageglass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/kiro-cli/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===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/krita/darwin.json=== Install Script (no changes) ===
=== Uninstall // 7b9f27dc -> 3947b0f0 ===
--- /tmp/old.OTEs9N 2026-08-07 15:53:21.167633783 +0000
+++ /tmp/new.uoByGl 2026-08-07 15:53:21.167633783 +0000
@@ -52,8 +52,11 @@
fi
}
-sudo rm -rf "$APPDIR/krita.app"
-trash $LOGGED_IN_USER '~/Library/Application Support/krita'
+sudo rm -rf "$APPDIR/Krita.app"
+trash $LOGGED_IN_USER '~/Library/Application Scripts/org.krita.*'
+trash $LOGGED_IN_USER '~/Library/Application Support/krita*'
+trash $LOGGED_IN_USER '~/Library/Caches/krita'
+trash $LOGGED_IN_USER '~/Library/Containers/org.krita.*'
trash $LOGGED_IN_USER '~/Library/Preferences/kritadisplayrc'
trash $LOGGED_IN_USER '~/Library/Preferences/kritarc'
trash $LOGGED_IN_USER '~/Library/Saved Application State/org.krita.savedState'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/marked-app/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/masscode/darwin.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-edge/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/mongodb-compass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nordpass/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nordpass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/notesnook/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nova/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/onedrive/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/opencode-desktop/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/opera/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/orbstack/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/p4v/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/p4v/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/pale-moon/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/parallels/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/postman/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/postman/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/powerphotos/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/prisma-browser/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/prisma-browser/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/proton-drive/darwin.json=== Install Script (no changes) ===
=== Uninstall // fc6f5099 -> ac89ef74 ===
--- /tmp/old.xkepBx 2026-08-07 15:53:22.057632561 +0000
+++ /tmp/new.WFGyvx 2026-08-07 15:53:22.057632561 +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,6 +122,7 @@
fi
}
+remove_launchctl_service 'ch.protonmail.drive.agent'
sudo rm -rf "$APPDIR/Proton Drive.app"
trash $LOGGED_IN_USER '~/Library/Application Scripts/ch.protonmail.drive*'
trash $LOGGED_IN_USER '~/Library/Application Support/FileProvider/ch.protonmail.drive.fileprovider'ee/maintained-apps/outputs/rider/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rive/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rustrover/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/shapr3d/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/spokenly/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/spotify/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/spyder/windows.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/sync/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/telegram/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/viscosity/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/viscosity/windows.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/windows-app/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/wispr-flow/darwin.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/xnconvert/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/zen/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) === |
The poll suppressed errors with -ErrorAction SilentlyContinue and read an empty result as proof of removal, so a failed registry query looked identical to a successful uninstall. The validator re-checks afterward, but on a real host the script's exit code is the only signal, so Fleet would have recorded a successful uninstall with Evernote still installed. Only an enumeration that actually succeeds may now clear the flag. Individual keys are still read leniently, since the uninstaller deletes keys while we walk them and those transient misses resolve on the next pass.
Script Diff Resultsee/maintained-apps/outputs/alt-tab/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/amadine/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/arc/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/badgeify/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/beekeeper-studio/windows.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/calibre/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/calibre/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/capcut/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/chatbox/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/chatgpt/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cherry-studio/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/claude/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cmake-app/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/codexbar/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/coteditor/darwin.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/deezer/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/downie/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/drofus/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/elevate-uc/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/evernote/windows.json=== Install Script (no changes) ===
=== Uninstall // a97ad90f -> 0f7cfea8 ===
--- /tmp/old.QYRC3O 2026-08-07 16:01:29.970890553 +0000
+++ /tmp/new.ZOYL4W 2026-08-07 16:01:29.971890575 +0000
@@ -81,15 +81,32 @@
$deadline = (Get-Date).AddSeconds(300)
do {
Start-Sleep -Seconds 5
- $stillInstalled = Get-ChildItem `
- -Path @($machineKey, $machineKey32on64) `
- -ErrorAction SilentlyContinue |
- ForEach-Object { Get-ItemProperty $_.PSPath } |
- Where-Object { $_.DisplayName -like $softwareNameLike }
+ # Fail closed: only an enumeration that actually succeeds may
+ # be read as proof of removal. If the query itself fails, the
+ # empty result says nothing about whether Evernote is gone,
+ # so keep the previous "still installed" answer rather than
+ # reporting a successful uninstall. Individual keys are still
+ # read leniently: the uninstaller deletes keys while we walk
+ # them, and those transient misses resolve on the next pass.
+ $stillInstalled = $true
+ try {
+ $stillInstalled = [bool](Get-ChildItem `
+ -Path @($machineKey, $machineKey32on64) `
+ -ErrorAction Stop |
+ ForEach-Object {
+ Get-ItemProperty $_.PSPath `
+ -ErrorAction SilentlyContinue
+ } |
+ Where-Object {
+ $_.DisplayName -like $softwareNameLike
+ })
+ } catch {
+ Write-Host "Could not query the uninstall registry: $_"
+ }
} while ($stillInstalled -and (Get-Date) -lt $deadline)
if ($stillInstalled) {
- Write-Host "'$softwareName' is still registered after waiting."
+ Write-Host "Could not confirm '$softwareName' was removed."
$exitCode = 1
} else {
Write-Host "'$softwareName' was removed."ee/maintained-apps/outputs/fellow/windows.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/framer/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/gitkraken/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/gog-galaxy/darwin.json=== Install // 9f170824 -> 89b9a1b7 ===
--- /tmp/old.8JER8J 2026-08-07 16:01:30.198895417 +0000
+++ /tmp/new.W0KNPJ 2026-08-07 16:01:30.198895417 +0000
@@ -96,5 +96,5 @@
# install pkg files
quit_and_track_application 'com.gog.galaxy.cef.renderer'
-sudo installer -pkg "$TMPDIR/galaxy_client_2.1.7.22.pkg" -target / || exit $?
+sudo installer -pkg "$TMPDIR/galaxy_client_2.1.8.32.pkg" -target / || exit $?
relaunch_application 'com.gog.galaxy.cef.renderer'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/google-chrome/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/ibm-semeru-jre-11/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/imageglass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/kiro-cli/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===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/krita/darwin.json=== Install Script (no changes) ===
=== Uninstall // 7b9f27dc -> 3947b0f0 ===
--- /tmp/old.UzlHui 2026-08-07 16:01:30.513902137 +0000
+++ /tmp/new.Kv6TTX 2026-08-07 16:01:30.513902137 +0000
@@ -52,8 +52,11 @@
fi
}
-sudo rm -rf "$APPDIR/krita.app"
-trash $LOGGED_IN_USER '~/Library/Application Support/krita'
+sudo rm -rf "$APPDIR/Krita.app"
+trash $LOGGED_IN_USER '~/Library/Application Scripts/org.krita.*'
+trash $LOGGED_IN_USER '~/Library/Application Support/krita*'
+trash $LOGGED_IN_USER '~/Library/Caches/krita'
+trash $LOGGED_IN_USER '~/Library/Containers/org.krita.*'
trash $LOGGED_IN_USER '~/Library/Preferences/kritadisplayrc'
trash $LOGGED_IN_USER '~/Library/Preferences/kritarc'
trash $LOGGED_IN_USER '~/Library/Saved Application State/org.krita.savedState'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/marked-app/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/masscode/darwin.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-edge/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/mongodb-compass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nordpass/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nordpass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/notesnook/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nova/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/onedrive/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/opencode-desktop/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/opera/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/orbstack/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/p4v/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/p4v/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/pale-moon/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/parallels/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/postman/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/postman/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/powerphotos/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/prisma-browser/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/prisma-browser/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/proton-drive/darwin.json=== Install Script (no changes) ===
=== Uninstall // fc6f5099 -> ac89ef74 ===
--- /tmp/old.2Si7XQ 2026-08-07 16:01:31.527923768 +0000
+++ /tmp/new.ujbrpE 2026-08-07 16:01:31.527923768 +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,6 +122,7 @@
fi
}
+remove_launchctl_service 'ch.protonmail.drive.agent'
sudo rm -rf "$APPDIR/Proton Drive.app"
trash $LOGGED_IN_USER '~/Library/Application Scripts/ch.protonmail.drive*'
trash $LOGGED_IN_USER '~/Library/Application Support/FileProvider/ch.protonmail.drive.fileprovider'ee/maintained-apps/outputs/rider/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rive/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rustrover/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/shapr3d/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/spokenly/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/spotify/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/spyder/windows.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/sync/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/telegram/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/viscosity/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/viscosity/windows.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/windows-app/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/wispr-flow/darwin.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/xnconvert/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/zen/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) === |
Script Diff Resultsee/maintained-apps/outputs/alt-tab/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/amadine/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/arc/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/badgeify/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/beekeeper-studio/windows.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/calibre/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/calibre/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/capcut/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/chatbox/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/chatgpt/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cherry-studio/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/claude/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/cmake-app/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/codexbar/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/coteditor/darwin.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/deezer/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/downie/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/drofus/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/elevate-uc/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/evernote/windows.json=== Install Script (no changes) ===
=== Uninstall // 0f7cfea8 -> 0c86d350 ===
--- /tmp/old.QeTUXL 2026-08-07 16:32:42.172308376 +0000
+++ /tmp/new.7NNrVq 2026-08-07 16:32:42.172308376 +0000
@@ -1,15 +1,10 @@
-# Fleet extracts name from installer (EXE) and saves it to PACKAGE_ID
-# variable
-# Evernote (electron-builder NSIS) registers a versioned DisplayName in HKLM
-# when installed with /allusers, e.g. "Evernote 11.24.3 (All Users)". The
-# "(All Users)" suffix is locale-dependent, so match on the "Evernote" prefix
-# only. Its QuietUninstallString runs "Uninstall Evernote.exe" /allusers /S,
-# which also closes the running tray app.
+# The "(All Users)" suffix in Evernote's DisplayName is locale-dependent, so
+# match on the "Evernote" prefix only.
$softwareName = "Evernote"
$softwareNameLike = "Evernote*"
-# electron-builder NSIS uninstaller; /allusers matches the machine-wide install
+# /allusers matches the machine-wide install
$uninstallArgs = "/allusers /S"
$machineKey = `
@@ -30,17 +25,12 @@
foreach ($key in $uninstallKeys) {
if ($key.DisplayName -like $softwareNameLike) {
$foundUninstaller = $true
- # Get the uninstall command. Some uninstallers do not include
- # 'QuietUninstallString' and require a flag to run silently.
$uninstallCommand = if ($key.QuietUninstallString) {
$key.QuietUninstallString
} else {
$key.UninstallString
}
- # The uninstall command may contain command and args, like:
- # "C:\Program Files\Software\uninstall.exe" /SILENT
- # Split the command and args
$splitArgs = $uninstallCommand.Split('"')
if ($splitArgs.Length -gt 1) {
if ($splitArgs.Length -eq 3) {
@@ -65,29 +55,20 @@
$processOptions.ArgumentList = "$uninstallArgs"
}
- # Start process and track exit code
$process = Start-Process @processOptions
$exitCode = $process.ExitCode
- # Prints the exit code
Write-Host "Uninstall exit code: $exitCode"
- # Without an "_?=<installdir>" argument, an NSIS uninstaller copies
- # itself to %TEMP%, relaunches the copy detached, and the process we
- # waited on exits 0 immediately -- so the removal is still in flight
- # here. Poll the uninstall registry key until the entry disappears so
- # this script only reports success once the app is really gone.
+ # Without an "_?=<installdir>" argument an NSIS uninstaller relaunches
+ # itself from %TEMP% and exits 0 before the removal finishes, so wait
+ # for the registry entry to clear.
if ($exitCode -eq 0) {
$deadline = (Get-Date).AddSeconds(300)
do {
Start-Sleep -Seconds 5
- # Fail closed: only an enumeration that actually succeeds may
- # be read as proof of removal. If the query itself fails, the
- # empty result says nothing about whether Evernote is gone,
- # so keep the previous "still installed" answer rather than
- # reporting a successful uninstall. Individual keys are still
- # read leniently: the uninstaller deletes keys while we walk
- # them, and those transient misses resolve on the next pass.
+ # Fail closed: a failed query is not proof of removal. Keys are
+ # read leniently since the uninstaller deletes them as we walk.
$stillInstalled = $true
try {
$stillInstalled = [bool](Get-ChildItem `
@@ -113,15 +94,12 @@
}
}
- # Exit the loop once the software is found and uninstalled.
break
}
}
if (-not $foundUninstaller) {
Write-Host "Uninstaller for '$softwareName' not found."
- # Change exit code to 0 if you don't want to fail if uninstaller is not
- # found. This could happen if program was already uninstalled.
$exitCode = 1
}ee/maintained-apps/outputs/fellow/windows.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/framer/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/gitkraken/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/gog-galaxy/darwin.json=== Install // 9f170824 -> 89b9a1b7 ===
--- /tmp/old.v8M1pD 2026-08-07 16:32:42.380312405 +0000
+++ /tmp/new.rtFgHr 2026-08-07 16:32:42.380312405 +0000
@@ -96,5 +96,5 @@
# install pkg files
quit_and_track_application 'com.gog.galaxy.cef.renderer'
-sudo installer -pkg "$TMPDIR/galaxy_client_2.1.7.22.pkg" -target / || exit $?
+sudo installer -pkg "$TMPDIR/galaxy_client_2.1.8.32.pkg" -target / || exit $?
relaunch_application 'com.gog.galaxy.cef.renderer'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/google-chrome/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/ibm-semeru-jre-11/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/imageglass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/kiro-cli/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===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/krita/darwin.json=== Install Script (no changes) ===
=== Uninstall // 7b9f27dc -> 3947b0f0 ===
--- /tmp/old.oVbVG4 2026-08-07 16:32:42.678318177 +0000
+++ /tmp/new.3iVHPi 2026-08-07 16:32:42.678318177 +0000
@@ -52,8 +52,11 @@
fi
}
-sudo rm -rf "$APPDIR/krita.app"
-trash $LOGGED_IN_USER '~/Library/Application Support/krita'
+sudo rm -rf "$APPDIR/Krita.app"
+trash $LOGGED_IN_USER '~/Library/Application Scripts/org.krita.*'
+trash $LOGGED_IN_USER '~/Library/Application Support/krita*'
+trash $LOGGED_IN_USER '~/Library/Caches/krita'
+trash $LOGGED_IN_USER '~/Library/Containers/org.krita.*'
trash $LOGGED_IN_USER '~/Library/Preferences/kritadisplayrc'
trash $LOGGED_IN_USER '~/Library/Preferences/kritarc'
trash $LOGGED_IN_USER '~/Library/Saved Application State/org.krita.savedState'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/marked-app/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/masscode/darwin.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-edge/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/mongodb-compass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nordpass/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nordpass/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/notesnook/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/nova/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/onedrive/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/opencode-desktop/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/opera/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/orbstack/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/p4v/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/p4v/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/pale-moon/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/parallels/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/postman/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/postman/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/powerphotos/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/prisma-browser/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/prisma-browser/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/proton-drive/darwin.json=== Install Script (no changes) ===
=== Uninstall // fc6f5099 -> ac89ef74 ===
--- /tmp/old.0WGka7 2026-08-07 16:32:43.640336810 +0000
+++ /tmp/new.Sw8Deh 2026-08-07 16:32:43.640336810 +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,6 +122,7 @@
fi
}
+remove_launchctl_service 'ch.protonmail.drive.agent'
sudo rm -rf "$APPDIR/Proton Drive.app"
trash $LOGGED_IN_USER '~/Library/Application Scripts/ch.protonmail.drive*'
trash $LOGGED_IN_USER '~/Library/Application Support/FileProvider/ch.protonmail.drive.fileprovider'ee/maintained-apps/outputs/rider/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rive/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/rustrover/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/shapr3d/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/spokenly/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/spotify/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/spyder/windows.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/sync/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/telegram/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/viscosity/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/viscosity/windows.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/windows-app/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/wispr-flow/darwin.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/xnconvert/windows.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/zen/darwin.json=== Install Script (no changes) ===
=== Uninstall Script (no changes) === |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@ee/maintained-apps/outputs/evernote/windows.json`:
- Line 19: Update the post-uninstall registry check in the $stillInstalled wait
loop to query $machineKey and $machineKey32on64 independently, treating a
missing path as empty rather than entering the catch with $stillInstalled true.
Preserve fail-closed behavior for other query errors, while allowing successful
uninstall completion when either registry path does not exist.
- Line 19: Update the uninstall loop around $foundUninstaller and the
$key.DisplayName check to require both DisplayName matching $softwareNameLike
and Publisher equaling "Evernote Corporation" before selecting or running an
uninstaller. Keep the existing command parsing and removal verification
unchanged.
- Line 19: Update the registry verification loop around $stillInstalled so any
Get-ItemProperty read failure keeps the installation state indeterminate rather
than allowing $stillInstalled to become false. Preserve the fail-closed result,
while handling only expected missing-key races as non-installed; adjust the
per-key error handling and surrounding query logic without changing the
successful removal path.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: b2f86e68-04c6-418b-b47b-78eafa0ce539
📒 Files selected for processing (2)
ee/maintained-apps/inputs/winget/scripts/evernote_uninstall.ps1ee/maintained-apps/outputs/evernote/windows.json
🚧 Files skipped from review as they are similar to previous changes (1)
- ee/maintained-apps/inputs/winget/scripts/evernote_uninstall.ps1
| "refs": { | ||
| "5820d576": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\ntry {\n\n# Evernote uses an electron-builder NSIS installer. It defaults to a per-user\n# install, so /allusers is required for a machine-wide install alongside the\n# NSIS /S silent flag.\n$processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"/allusers /S\"\n PassThru = $true\n Wait = $true\n}\n\n# Start process and track exit code\n$process = Start-Process @processOptions\n$exitCode = $process.ExitCode\n\n# Prints the exit code\nWrite-Host \"Install exit code: $exitCode\"\nExit $exitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n", | ||
| "d4142835": "# Fleet extracts name from installer (EXE) and saves it to PACKAGE_ID\n# variable\n# Evernote (electron-builder NSIS) registers a versioned DisplayName in HKLM\n# when installed with /allusers, e.g. \"Evernote 11.24.3 (All Users)\". The\n# \"(All Users)\" suffix is locale-dependent, so match on the \"Evernote\" prefix\n# only. Its QuietUninstallString runs \"Uninstall Evernote.exe\" /allusers /S,\n# which also closes the running tray app.\n$softwareName = \"Evernote\"\n\n$softwareNameLike = \"Evernote*\"\n\n# electron-builder NSIS uninstaller; /allusers matches the machine-wide install\n$uninstallArgs = \"/allusers /S\"\n\n$machineKey = `\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*'\n$machineKey32on64 = `\n 'HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*'\n\n$exitCode = 0\n\ntry {\n\n[array]$uninstallKeys = Get-ChildItem `\n -Path @($machineKey, $machineKey32on64) `\n -ErrorAction SilentlyContinue |\n ForEach-Object { Get-ItemProperty $_.PSPath }\n\n$foundUninstaller = $false\nforeach ($key in $uninstallKeys) {\n if ($key.DisplayName -like $softwareNameLike) {\n $foundUninstaller = $true\n # Get the uninstall command. Some uninstallers do not include\n # 'QuietUninstallString' and require a flag to run silently.\n $uninstallCommand = if ($key.QuietUninstallString) {\n $key.QuietUninstallString\n } else {\n $key.UninstallString\n }\n\n # The uninstall command may contain command and args, like:\n # \"C:\\Program Files\\Software\\uninstall.exe\" /SILENT\n # Split the command and args\n $splitArgs = $uninstallCommand.Split('\"')\n if ($splitArgs.Length -gt 1) {\n if ($splitArgs.Length -eq 3) {\n $uninstallArgs = \"$( $splitArgs[2] ) $uninstallArgs\".Trim()\n } elseif ($splitArgs.Length -gt 3) {\n Throw `\n \"Uninstall command contains multiple quoted strings. \" +\n \"Please update the uninstall script.`n\" +\n \"Uninstall command: $uninstallCommand\"\n }\n $uninstallCommand = $splitArgs[1]\n }\n Write-Host \"Uninstall command: $uninstallCommand\"\n Write-Host \"Uninstall args: $uninstallArgs\"\n\n $processOptions = @{\n FilePath = $uninstallCommand\n PassThru = $true\n Wait = $true\n }\n if ($uninstallArgs -ne '') {\n $processOptions.ArgumentList = \"$uninstallArgs\"\n }\n\n # Start process and track exit code\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n\n # Prints the exit code\n Write-Host \"Uninstall exit code: $exitCode\"\n # Exit the loop once the software is found and uninstalled.\n break\n }\n}\n\nif (-not $foundUninstaller) {\n Write-Host \"Uninstaller for '$softwareName' not found.\"\n # Change exit code to 0 if you don't want to fail if uninstaller is not\n # found. This could happen if program was already uninstalled.\n $exitCode = 1\n}\n\n} catch {\n Write-Host \"Error: $_\"\n $exitCode = 1\n}\n\nExit $exitCode\n" | ||
| "0c86d350": "# The \"(All Users)\" suffix in Evernote's DisplayName is locale-dependent, so\n# match on the \"Evernote\" prefix only.\n$softwareName = \"Evernote\"\n\n$softwareNameLike = \"Evernote*\"\n\n# /allusers matches the machine-wide install\n$uninstallArgs = \"/allusers /S\"\n\n$machineKey = `\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*'\n$machineKey32on64 = `\n 'HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*'\n\n$exitCode = 0\n\ntry {\n\n[array]$uninstallKeys = Get-ChildItem `\n -Path @($machineKey, $machineKey32on64) `\n -ErrorAction SilentlyContinue |\n ForEach-Object { Get-ItemProperty $_.PSPath }\n\n$foundUninstaller = $false\nforeach ($key in $uninstallKeys) {\n if ($key.DisplayName -like $softwareNameLike) {\n $foundUninstaller = $true\n $uninstallCommand = if ($key.QuietUninstallString) {\n $key.QuietUninstallString\n } else {\n $key.UninstallString\n }\n\n $splitArgs = $uninstallCommand.Split('\"')\n if ($splitArgs.Length -gt 1) {\n if ($splitArgs.Length -eq 3) {\n $uninstallArgs = \"$( $splitArgs[2] ) $uninstallArgs\".Trim()\n } elseif ($splitArgs.Length -gt 3) {\n Throw `\n \"Uninstall command contains multiple quoted strings. \" +\n \"Please update the uninstall script.`n\" +\n \"Uninstall command: $uninstallCommand\"\n }\n $uninstallCommand = $splitArgs[1]\n }\n Write-Host \"Uninstall command: $uninstallCommand\"\n Write-Host \"Uninstall args: $uninstallArgs\"\n\n $processOptions = @{\n FilePath = $uninstallCommand\n PassThru = $true\n Wait = $true\n }\n if ($uninstallArgs -ne '') {\n $processOptions.ArgumentList = \"$uninstallArgs\"\n }\n\n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n\n Write-Host \"Uninstall exit code: $exitCode\"\n\n # Without an \"_?=<installdir>\" argument an NSIS uninstaller relaunches\n # itself from %TEMP% and exits 0 before the removal finishes, so wait\n # for the registry entry to clear.\n if ($exitCode -eq 0) {\n $deadline = (Get-Date).AddSeconds(300)\n do {\n Start-Sleep -Seconds 5\n # Fail closed: a failed query is not proof of removal. Keys are\n # read leniently since the uninstaller deletes them as we walk.\n $stillInstalled = $true\n try {\n $stillInstalled = [bool](Get-ChildItem `\n -Path @($machineKey, $machineKey32on64) `\n -ErrorAction Stop |\n ForEach-Object {\n Get-ItemProperty $_.PSPath `\n -ErrorAction SilentlyContinue\n } |\n Where-Object {\n $_.DisplayName -like $softwareNameLike\n })\n } catch {\n Write-Host \"Could not query the uninstall registry: $_\"\n }\n } while ($stillInstalled -and (Get-Date) -lt $deadline)\n\n if ($stillInstalled) {\n Write-Host \"Could not confirm '$softwareName' was removed.\"\n $exitCode = 1\n } else {\n Write-Host \"'$softwareName' was removed.\"\n }\n }\n\n break\n }\n}\n\nif (-not $foundUninstaller) {\n Write-Host \"Uninstaller for '$softwareName' not found.\"\n $exitCode = 1\n}\n\n} catch {\n Write-Host \"Error: $_\"\n $exitCode = 1\n}\n\nExit $exitCode\n", |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate and inspect the relevant Windows manifest/script around the cited line.
if [ -f ee/maintained-apps/outputs/evernote/windows.json ]; then
wc -l ee/maintained-apps/outputs/evernote/windows.json
sed -n '1,80p' ee/maintained-apps/outputs/evernote/windows.json
else
echo "file missing"
fi
# Use Python to model the exact registry query/split/fallback behavior from the script
# without executing repository code.
python3 - <<'PY'
from pathlib import Path
import ast, json, re
path = Path("ee/maintained-apps/outputs/evernote/windows.json")
if not path.exists():
raise SystemExit("missing")
text = path.read_text()
try:
data = json.loads(text)
except Exception as e:
print("json_parse_error:", type(e).__name__, e)
data = {}
print("keys:", list(data.keys()))
if "uninstall" in data:
script = data["uninstall"]
# Print only the relevant registry loop region without modifying anything.
lines = script.splitlines()
for i, line in enumerate(lines, 1):
if "Get-ChildItem -ErrorAction Stop" in line or "stillInstalled = [bool]" in line or "if ($stillInstalled) {" in line:
start = max(1, i-8)
end = min(len(lines), i+40)
print(f"\n--- region around line {i} ---")
for n in range(start, end+1):
print(f"{n:04d}: {lines[n-1]}")
break
# Parse the embedded PowerShell strings as data by reading a generated helper function
# if convenient; no repository code is executed. The concern is deterministic when
# Get-ChildItem stops instead of silently returning and catch leaves state unchanged.
print("\n--- static evidence for registry query behavior ---")
for needle in ["Get-ChildItem`n -Path `", "-ErrorAction Stop", "-ErrorAction SilentlyContinue", "$foundUninstaller = $false"]:
print(needle, ("YES" if needle in data.get("uninstall", "") else "NO"))
PYRepository: fleetdm/fleet
Length of output: 5822
Handle missing registry paths without delaying uninstall success.
Get-ChildItem -ErrorAction Stop queries both registry paths in one operation. If either path is absent, the catch block leaves $stillInstalled set to $true; the script then sleeps for up to 300 seconds and exits 1. Query each registry path independently and treat a nonexistent path as an empty view before the wait loop.
🤖 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/evernote/windows.json` at line 19, Update the
post-uninstall registry check in the $stillInstalled wait loop to query
$machineKey and $machineKey32on64 independently, treating a missing path as
empty rather than entering the catch with $stillInstalled true. Preserve
fail-closed behavior for other query errors, while allowing successful uninstall
completion when either registry path does not exist.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== files =="
git ls-files | rg '(^|/)ee/maintained-apps/outputs/evernote/windows\.json$|maintained-apps/output' || true
echo "== target file =="
cat -n ee/maintained-apps/outputs/evernote/windows.json
echo "== related evernote files =="
git ls-files | rg 'evernote|Evernote' | sed -n '1,120p'Repository: fleetdm/fleet
Length of output: 50369
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== target file exact =="
wc -l ee/maintained-apps/outputs/evernote/windows.json
cat -n ee/maintained-apps/outputs/evernote/windows.json | sed -n '1,100p'
echo "== evernote files =="
for f in ee/maintained-apps/outputs/evernote/*; do echo "--- $f"; sed -n '1,120p' "$f"; done
echo "== similar registry publisher patterns =="
rg -n "DisplayName -like|publisher|Publisher|Uninstaller|Softpedia" ee/maintained-apps/outputs -g '*windows.json' | sed -n '1,220p'Repository: fleetdm/fleet
Length of output: 50370
Match Evernote’s registry publisher before uninstalling.
The version query requires publisher = 'Evernote Corporation', but the uninstaller runs on any registry entry where DisplayName -like "Evernote*". Add the same publisher filter in the uninstall loop so a different Evernote-titled product cannot be uninstalled.
🤖 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/evernote/windows.json` at line 19, Update the
uninstall loop around $foundUninstaller and the $key.DisplayName check to
require both DisplayName matching $softwareNameLike and Publisher equaling
"Evernote Corporation" before selecting or running an uninstaller. Keep the
existing command parsing and removal verification unchanged.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== target file excerpt =="
sed -n '1,220p' ee/maintained-apps/outputs/evernote/windows.json | cat -n
echo
echo "== references to get-itemproperty and stillinstalled patterns =="
rg -n "Get-ItemProperty|stillInstalled|Could not confirm|Could not query the uninstall registry" ee/maintained-apps/outputs/evernote/windows.jsonRepository: fleetdm/fleet
Length of output: 9719
🌐 Web query:
PowerShell Get-ItemProperty -ErrorAction SilentlyContinue silentlyContinue exception item not found
💡 Result:
The error you are encountering occurs because Get-ItemProperty (and its counterpart Get-ItemPropertyValue) often throws a terminating exception when a path or property cannot be found, which bypasses the standard -ErrorAction SilentlyContinue parameter [1][2]. In PowerShell, -ErrorAction is designed to handle non-terminating errors [2]. When a cmdlet explicitly calls a terminating error (such as an ItemNotFoundException), the -ErrorAction parameter is ignored [2]. To handle this gracefully, you should use the following strategies: 1. Use Test-Path: The most robust approach is to verify the existence of the registry key or property before attempting to read it [3][4]. This prevents the terminating error from occurring in the first place [4]. if (Test-Path -Path 'HKLM:\Software\MyKey') { $value = Get-ItemProperty -Path 'HKLM:\Software\MyKey' -Name 'MyValue' } 2. Use Try/Catch Blocks: Since these are terminating errors, you can catch them using a standard try/catch block [2][5]. try { $value = Get-ItemProperty -Path 'HKLM:\Software\MyKey' -Name 'MyValue' -ErrorAction Stop } catch [System.Management.Automation.ItemNotFoundException] { Write-Warning "The registry path was not found." } 3. Check Architecture (32-bit vs 64-bit): If you are certain the registry key exists but PowerShell still reports it as missing, you may be running a 32-bit version of PowerShell on a 64-bit operating system [6][7]. This causes registry redirection, where the script looks into the WOW6432Node instead of the expected path [7]. To resolve this, run your script using the 64-bit version of PowerShell located at %SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe [7]. Finally, note that Get-ItemProperty can sometimes return null without an error if the path exists but the specific property does not [3]. Always validate the returned object to ensure the data you retrieved is not null before using it in your logic [4].
Citations:
- 1: Get-ItemPropertyValue ignores ErrorAction SilentlyContinue if registry key does not exist PowerShell/PowerShell#5906
- 2: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_error_handling?view=powershell-7.6
- 3: https://thelinuxcode.com/how-do-i-get-the-value-of-a-registry-key-and-only-the-value-using-powershell/
- 4: https://sysadminsage.com/powershell-get-registry-key-value/
- 5: https://devblogs.microsoft.com/scripting/catch-powershell-errors-related-to-reading-the-registry/
- 6: https://stackoverflow.com/questions/18709222/get-itemproperty-reporting-item-doesnt-exist-when-it-does
- 7: Get-Item(Property)/Get-ChildItem doesn't find existing registry key PowerShell/PowerShell#20680
🌐 Web query:
PowerShell SilentlyContinue handling non-terminating errors pipeline iteration
💡 Result:
In PowerShell, SilentlyContinue is a preference setting that instructs the shell to suppress error messages and continue execution when a command encounters a non-terminating error [1][2][3]. When used in a pipeline, SilentlyContinue ensures that the pipeline does not stop when a cmdlet encounters an error [1][2]. Instead, the cmdlet simply suppresses the error output for the specific item it is processing and proceeds to the next item in the pipeline [2][4]. Key behavioral points regarding this configuration include: - Pipeline Iteration: Because non-terminating errors (by definition) do not halt the cmdlet's processing, setting the preference to SilentlyContinue allows the pipeline to continue iterating through all input objects without interruption, even if errors occur for some items [4][5][6]. - Error Recording: Unlike the Ignore preference, which suppresses both the message and the error recording, SilentlyContinue still adds the error record to the automatic $Error variable [2][3][7]. This allows you to inspect the errors after the pipeline has finished execution [5][7]. - Tracking Specific Iterations: To distinguish errors occurring during pipeline iteration, it is often best to use the -ErrorVariable common parameter [4][5]. This allows you to capture errors from a specific command into a named variable (e.g., -ErrorVariable myErrors), which you can then inspect or iterate over after the pipeline completes [4][5][7]. - Scope: The $ErrorActionPreference variable affects all commands within the scope where it is set [8][2]. For precise control, use the -ErrorAction common parameter on the specific cmdlet instead, which overrides the preference variable for that single command [1][2][3]. In summary, for pipeline operations where you expect some failures but want processing to complete for all items, use -ErrorAction SilentlyContinue combined with -ErrorVariable to reliably capture and review all non-terminating errors post-execution [5][7].
Citations:
- 1: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.4
- 2: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.6
- 3: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.4
- 4: https://devblogs.microsoft.com/powershell/managing-non-terminating-errors/
- 5: https://www.powershelltips.com/powershell-terminating-vs-non-terminating-errors/
- 6: https://learn.microsoft.com/en-us/powershell/scripting/developer/cmdlet/adding-non-terminating-error-reporting-to-your-cmdlet?view=powershell-7.6
- 7: https://stackoverflow.com/questions/75044948/powershell-erroraction-silentlycontinue-not-adding-error-to-error-variable
- 8: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_error_handling?view=powershell-7.6
Preserve fail-closed behavior for registry read failures.
In this retry loop, Get-ItemProperty -ErrorAction SilentlyContinue can drop an Evernote uninstall key whose properties cannot be read. That can make $stillInstalled become $false and report successful removal although the install state is indeterminate. Keep the state indeterminate on read failures, and handle expected uninstaller race conditions only for missing keys.
🤖 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/evernote/windows.json` at line 19, Update the
registry verification loop around $stillInstalled so any Get-ItemProperty read
failure keeps the installation state indeterminate rather than allowing
$stillInstalled to become false. Preserve the fail-closed result, while handling
only expected missing-key races as non-installed; adjust the per-key error
handling and surrounding query logic without changing the successful removal
path.
Automated ingestion of latest Fleet-maintained app data.
Summary by CodeRabbit
Updates
Bug Fixes
Configuration