Skip to content

Update Fleet-maintained apps - #46695

Merged
allenhouchins merged 1 commit into
mainfrom
fma-2606030033
Jun 3, 2026
Merged

Update Fleet-maintained apps#46695
allenhouchins merged 1 commit into
mainfrom
fma-2606030033

Conversation

@fleet-release

@fleet-release fleet-release commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Automated ingestion of latest Fleet-maintained app data.

Summary by CodeRabbit

  • Chores
    • Updated managed application packages to their latest versions across macOS and Windows platforms. Includes version updates for 1Password, Android Studio, AWS CLI, Camtasia, Claude, Cursor, Discord, Docker, Duo Desktop, Figma, Firefox, GitKraken, Google Chrome, Gemini, Granola, iTerm2, JetBrains Toolbox, Loom, Microsoft Office applications, Miro, NordPass, Notion, RustDesk, and WhatsApp installations.

Generated automatically with cmd/maintained-apps.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/1password/darwin.json

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

ee/maintained-apps/outputs/android-studio/darwin.json

=== Install Script (no changes) ===
=== Uninstall // 237e23f1 -> aa386b1a ===

--- /tmp/old.K23HL0	2026-06-03 00:37:45.360593211 +0000
+++ /tmp/new.mpKJCq	2026-06-03 00:37:45.360593211 +0000
@@ -57,9 +57,9 @@
 sudo rmdir '~/Library/Android'
 trash $LOGGED_IN_USER '~/.android'
 trash $LOGGED_IN_USER '~/Library/Android/sdk'
-trash $LOGGED_IN_USER '~/Library/Application Support/Google/AndroidStudio2025.3'
-trash $LOGGED_IN_USER '~/Library/Caches/Google/AndroidStudio2025.3'
-trash $LOGGED_IN_USER '~/Library/Logs/Google/AndroidStudio2025.3'
+trash $LOGGED_IN_USER '~/Library/Application Support/Google/AndroidStudio2026.1'
+trash $LOGGED_IN_USER '~/Library/Caches/Google/AndroidStudio2026.1'
+trash $LOGGED_IN_USER '~/Library/Logs/Google/AndroidStudio2026.1'
 trash $LOGGED_IN_USER '~/Library/Preferences/com.android.Emulator.plist'
 trash $LOGGED_IN_USER '~/Library/Preferences/com.google.android.studio.plist'
 trash $LOGGED_IN_USER '~/Library/Saved Application State/com.google.android.studio.savedState'

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

=== Install // 4b0de65e -> 59f492ab ===

--- /tmp/old.PBuZlM	2026-06-03 00:37:45.631593933 +0000
+++ /tmp/new.0wrGdM	2026-06-03 00:37:45.631593933 +0000
@@ -96,5 +96,5 @@
 
 # install pkg files
 quit_and_track_application 'com.duosecurity.duo-device-health'
-sudo installer -pkg "$TMPDIR/DuoDesktop-7.17.0.0.pkg" -target /
+sudo installer -pkg "$TMPDIR/DuoDesktop-7.18.0.0.pkg" -target /
 relaunch_application 'com.duosecurity.duo-device-health'

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

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

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

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

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

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

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

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

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

ee/maintained-apps/outputs/google-chrome/darwin.json

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

ee/maintained-apps/outputs/google-gemini/darwin.json

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

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

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

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

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

ee/maintained-apps/outputs/jetbrains-toolbox/darwin.json

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

ee/maintained-apps/outputs/jetbrains-toolbox/windows.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/microsoft-excel/darwin.json

=== Install // 9a0e33ee -> f21e4176 ===

--- /tmp/old.la4EnY	2026-06-03 00:37:46.024594980 +0000
+++ /tmp/new.Z3wEPr	2026-06-03 00:37:46.024594980 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.109.26052523_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.109.26053122_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Excel'

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

ee/maintained-apps/outputs/microsoft-onenote/darwin.json

=== Install // d139e1b8 -> bee978c7 ===

--- /tmp/old.94Bfq5	2026-06-03 00:37:46.071595105 +0000
+++ /tmp/new.X5jFog	2026-06-03 00:37:46.071595105 +0000
@@ -96,5 +96,5 @@
 
 # install pkg files
 quit_and_track_application 'com.microsoft.onenote.mac'
-sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.109.26052523_Updater.pkg" -target /
+sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.109.26053122_Updater.pkg" -target /
 relaunch_application 'com.microsoft.onenote.mac'

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

ee/maintained-apps/outputs/microsoft-outlook/darwin.json

=== Install // 0e4e4b82 -> 6372af77 ===

--- /tmp/old.QQzfvu	2026-06-03 00:37:46.118595230 +0000
+++ /tmp/new.tVlntd	2026-06-03 00:37:46.119595233 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Outlook_16.109.26052523_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Outlook_16.109.26053122_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Outlook'

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

ee/maintained-apps/outputs/microsoft-powerpoint/darwin.json

=== Install // af592be8 -> 4b7d679c ===

--- /tmp/old.Y2WrSG	2026-06-03 00:37:46.172595374 +0000
+++ /tmp/new.1SwoUg	2026-06-03 00:37:46.172595374 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.109.26052523_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.109.26053122_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Powerpoint'

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

ee/maintained-apps/outputs/microsoft-word/darwin.json

=== Install // 5ba28779 -> b107fcf1 ===

--- /tmp/old.t5ATsW	2026-06-03 00:37:46.225595515 +0000
+++ /tmp/new.oCuXYJ	2026-06-03 00:37:46.225595515 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.109.26052523_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.109.26053122_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Word'

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

ee/maintained-apps/outputs/miro/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/notion/windows.json

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

ee/maintained-apps/outputs/rustdesk/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) ===

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR updates version metadata for 34 maintained applications across macOS and Windows platforms. Most updates follow a standard pattern: bumping the app version string, updating the patch-detection SQL predicate to compare against the new version threshold, changing the installer URL, and replacing the SHA256 checksum. Five Microsoft Office applications (Excel, OneNote, Outlook, PowerPoint, Word) also include changes to install script references and embedded installation script payloads. The updates span application manifests in ee/maintained-apps/outputs/ and enable deployment of newer versions through the managed apps infrastructure.

Possibly Related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is minimal but appropriate for an automated data ingestion. However, it lacks the structured format and required checklist items from the repository template. Add the repository's PR template structure with relevant checklist items marked. Since this is automated app data ingestion, clearly indicate which template sections apply and mark inapplicable items as N/A.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Update Fleet-maintained apps' directly and clearly describes the main change: updating version metadata and installer information for multiple Fleet-maintained applications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fma-2606030033

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 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/microsoft-word/darwin.json`:
- Line 19: The quit_application function's early-return guard uses osascript
exit status which is always 0 even when the script evaluates to false; change it
to capture osascript stdout (e.g., app_running=$(osascript -e "application id
\"$bundle_id\" is running" 2>/dev/null)) and then explicitly check if
app_running == "true" before proceeding (return when not "true"); update the
reference in quit_application where bundle_id is used and preserve the existing
stderr redirection.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d38b9a4f-f6ec-4b7b-80f5-20536cd814df

📥 Commits

Reviewing files that changed from the base of the PR and between fa7d928 and 4b49e9f.

📒 Files selected for processing (31)
  • ee/maintained-apps/outputs/1password/darwin.json
  • ee/maintained-apps/outputs/android-studio/darwin.json
  • ee/maintained-apps/outputs/android-studio/windows.json
  • ee/maintained-apps/outputs/aws-cli/windows.json
  • ee/maintained-apps/outputs/camtasia/darwin.json
  • ee/maintained-apps/outputs/claude/windows.json
  • ee/maintained-apps/outputs/cursor/windows.json
  • ee/maintained-apps/outputs/discord/windows.json
  • ee/maintained-apps/outputs/docker/windows.json
  • ee/maintained-apps/outputs/duo-desktop/darwin.json
  • ee/maintained-apps/outputs/figma/windows.json
  • ee/maintained-apps/outputs/firefox/darwin.json
  • ee/maintained-apps/outputs/firefox/windows.json
  • ee/maintained-apps/outputs/gitkraken/darwin.json
  • ee/maintained-apps/outputs/google-chrome/darwin.json
  • ee/maintained-apps/outputs/google-gemini/darwin.json
  • ee/maintained-apps/outputs/granola/windows.json
  • ee/maintained-apps/outputs/iterm2/darwin.json
  • ee/maintained-apps/outputs/jetbrains-toolbox/darwin.json
  • ee/maintained-apps/outputs/jetbrains-toolbox/windows.json
  • ee/maintained-apps/outputs/loom/windows.json
  • ee/maintained-apps/outputs/microsoft-excel/darwin.json
  • ee/maintained-apps/outputs/microsoft-onenote/darwin.json
  • ee/maintained-apps/outputs/microsoft-outlook/darwin.json
  • ee/maintained-apps/outputs/microsoft-powerpoint/darwin.json
  • ee/maintained-apps/outputs/microsoft-word/darwin.json
  • ee/maintained-apps/outputs/miro/darwin.json
  • ee/maintained-apps/outputs/nordpass/windows.json
  • ee/maintained-apps/outputs/notion/windows.json
  • ee/maintained-apps/outputs/rustdesk/darwin.json
  • ee/maintained-apps/outputs/whatsapp/darwin.json

"refs": {
"5ba28779": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# install pkg files\nquit_and_track_application 'com.microsoft.Word'\n\nCHOICE_XML=$(mktemp /tmp/choice_xml_XXX)\n\ncat << EOF > \"$CHOICE_XML\"\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<array>\n <dict>\n <key>attributeSetting</key>\n <integer>0</integer>\n <key>choiceAttribute</key>\n <string>selected</string>\n <key>choiceIdentifier</key>\n <string>com.microsoft.autoupdate</string>\n </dict>\n</array>\n</plist>\n\nEOF\n\nsudo installer -pkg \"$TMPDIR\"/Microsoft_Word_16.109.26052523_Installer.pkg -target / -applyChoiceChangesXML \"$CHOICE_XML\"\n\nrelaunch_application 'com.microsoft.Word'\n",
"6d6819ed": "#!/bin/bash\n\n# variables\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nexpand_pkgid_and_map() {\n local PKGID=\"$1\"\n local FUNC=\"$2\"\n if [[ \"$PKGID\" == *\"*\" ]]; then\n local prefix=\"${PKGID%\\*}\"\n echo \"Expanding wildcard for PKGID: $PKGID\"\n for receipt in $(pkgutil --pkgs | grep \"^${prefix}\"); do\n echo \"Processing $receipt\"\n \"$FUNC\" \"$receipt\"\n done\n else\n \"$FUNC\" \"$PKGID\"\n fi\n}\n\nforget_pkg() {\n local PKGID=\"$1\"\n expand_pkgid_and_map \"$PKGID\" forget_receipt\n}\n\nforget_receipt() {\n local PKGID=\"$1\"\n sudo pkgutil --forget \"$PKGID\"\n}\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n if ! osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ $EUID -eq 0 && \"$console_user\" == \"root\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nremove_launchctl_service() {\n local service=\"$1\"\n local booleans=(\"true\" \"false\")\n local plist_status\n local paths\n local should_sudo\n\n echo \"Removing launchctl service ${service}\"\n\n for should_sudo in \"${booleans[@]}\"; do\n plist_status=$(launchctl list \"${service}\" 2>/dev/null)\n\n if [[ $plist_status == \\{* ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo launchctl remove \"${service}\"\n else\n launchctl remove \"${service}\"\n fi\n sleep 1\n fi\n\n paths=(\n \"/Library/LaunchAgents/${service}.plist\"\n \"/Library/LaunchDaemons/${service}.plist\"\n )\n\n # if not using sudo, prepend the home directory to the paths\n if [[ $should_sudo == \"false\" ]]; then\n for i in \"${!paths[@]}\"; do\n paths[i]=\"${HOME}${paths[i]}\"\n done\n fi\n\n for path in \"${paths[@]}\"; do\n if [[ -e \"$path\" ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo rm -f -- \"$path\"\n else\n rm -f -- \"$path\"\n fi\n fi\n done\n done\n}\n\nremove_pkg_files() {\n local PKGID=\"$1\"\n expand_pkgid_and_map \"$PKGID\" remove_receipt_files\n}\n\nremove_receipt_files() {\n local PKGID=\"$1\"\n local PKGINFO VOLUME INSTALL_LOCATION FULL_INSTALL_LOCATION\n\n echo \"pkgutil --pkg-info-plist \\\"$PKGID\\\"\"\n PKGINFO=$(pkgutil --pkg-info-plist \"$PKGID\")\n VOLUME=$(echo \"$PKGINFO\" | awk '/<key>volume<\\/key>/ {getline; gsub(/.*<string>|<\\/string>.*/, \"\"); print}')\n INSTALL_LOCATION=$(echo \"$PKGINFO\" | awk '/<key>install-location<\\/key>/ {getline; gsub(/.*<string>|<\\/string>.*/, \"\"); print}')\n\n if [ -z \"$INSTALL_LOCATION\" ] || [ \"$INSTALL_LOCATION\" = \"/\" ]; then\n FULL_INSTALL_LOCATION=\"$VOLUME\"\n else\n FULL_INSTALL_LOCATION=\"$VOLUME/$INSTALL_LOCATION\"\n FULL_INSTALL_LOCATION=$(echo \"$FULL_INSTALL_LOCATION\" | sed 's|//|/|g')\n fi\n\n echo \"sudo pkgutil --only-files --files \\\"$PKGID\\\" | sed \\\"s|^|${FULL_INSTALL_LOCATION}/|\\\" | tr '\\\\\\\\n' '\\\\\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\"\n sudo pkgutil --only-files --files \"$PKGID\" | sed \"s|^|/${INSTALL_LOCATION}/|\" | tr '\\n' '\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\n\n echo \"sudo pkgutil --only-dirs --files \\\"$PKGID\\\" | sed \\\"s|^|${FULL_INSTALL_LOCATION}/|\\\" | grep '\\\\.app$' | tr '\\\\\\\\n' '\\\\\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\"\n sudo pkgutil --only-dirs --files \"$PKGID\" | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" | grep '\\.app$' | tr '\\n' '\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\n\n root_app_dir=$(\n sudo pkgutil --only-dirs --files \"$PKGID\" \\\n | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" \\\n | grep 'Applications' \\\n | awk '{ print length, $0 }' \\\n | sort -n \\\n | head -n1 \\\n | cut -d' ' -f2-\n )\n if [ -n \"$root_app_dir\" ]; then\n echo \"sudo rmdir -p \\\"$root_app_dir\\\" 2>/dev/null || :\"\n sudo rmdir -p \"$root_app_dir\" 2>/dev/null || :\n fi\n}\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nremove_launchctl_service 'com.microsoft.office.licensingV2.helper'\nquit_application 'com.microsoft.autoupdate2'\nremove_pkg_files 'com.microsoft.package.Microsoft_Word.app'\nforget_pkg 'com.microsoft.package.Microsoft_Word.app'\nremove_pkg_files 'com.microsoft.pkg.licensing'\nforget_pkg 'com.microsoft.pkg.licensing'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.microsoft.Word'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.microsoft.word.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/CrashReporter/Microsoft Word_*.plist'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.microsoft.Word'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.microsoft.Word.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.microsoft.Word.savedState'\n"
"6d6819ed": "#!/bin/bash\n\n# variables\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nexpand_pkgid_and_map() {\n local PKGID=\"$1\"\n local FUNC=\"$2\"\n if [[ \"$PKGID\" == *\"*\" ]]; then\n local prefix=\"${PKGID%\\*}\"\n echo \"Expanding wildcard for PKGID: $PKGID\"\n for receipt in $(pkgutil --pkgs | grep \"^${prefix}\"); do\n echo \"Processing $receipt\"\n \"$FUNC\" \"$receipt\"\n done\n else\n \"$FUNC\" \"$PKGID\"\n fi\n}\n\nforget_pkg() {\n local PKGID=\"$1\"\n expand_pkgid_and_map \"$PKGID\" forget_receipt\n}\n\nforget_receipt() {\n local PKGID=\"$1\"\n sudo pkgutil --forget \"$PKGID\"\n}\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n if ! osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ $EUID -eq 0 && \"$console_user\" == \"root\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nremove_launchctl_service() {\n local service=\"$1\"\n local booleans=(\"true\" \"false\")\n local plist_status\n local paths\n local should_sudo\n\n echo \"Removing launchctl service ${service}\"\n\n for should_sudo in \"${booleans[@]}\"; do\n plist_status=$(launchctl list \"${service}\" 2>/dev/null)\n\n if [[ $plist_status == \\{* ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo launchctl remove \"${service}\"\n else\n launchctl remove \"${service}\"\n fi\n sleep 1\n fi\n\n paths=(\n \"/Library/LaunchAgents/${service}.plist\"\n \"/Library/LaunchDaemons/${service}.plist\"\n )\n\n # if not using sudo, prepend the home directory to the paths\n if [[ $should_sudo == \"false\" ]]; then\n for i in \"${!paths[@]}\"; do\n paths[i]=\"${HOME}${paths[i]}\"\n done\n fi\n\n for path in \"${paths[@]}\"; do\n if [[ -e \"$path\" ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo rm -f -- \"$path\"\n else\n rm -f -- \"$path\"\n fi\n fi\n done\n done\n}\n\nremove_pkg_files() {\n local PKGID=\"$1\"\n expand_pkgid_and_map \"$PKGID\" remove_receipt_files\n}\n\nremove_receipt_files() {\n local PKGID=\"$1\"\n local PKGINFO VOLUME INSTALL_LOCATION FULL_INSTALL_LOCATION\n\n echo \"pkgutil --pkg-info-plist \\\"$PKGID\\\"\"\n PKGINFO=$(pkgutil --pkg-info-plist \"$PKGID\")\n VOLUME=$(echo \"$PKGINFO\" | awk '/<key>volume<\\/key>/ {getline; gsub(/.*<string>|<\\/string>.*/, \"\"); print}')\n INSTALL_LOCATION=$(echo \"$PKGINFO\" | awk '/<key>install-location<\\/key>/ {getline; gsub(/.*<string>|<\\/string>.*/, \"\"); print}')\n\n if [ -z \"$INSTALL_LOCATION\" ] || [ \"$INSTALL_LOCATION\" = \"/\" ]; then\n FULL_INSTALL_LOCATION=\"$VOLUME\"\n else\n FULL_INSTALL_LOCATION=\"$VOLUME/$INSTALL_LOCATION\"\n FULL_INSTALL_LOCATION=$(echo \"$FULL_INSTALL_LOCATION\" | sed 's|//|/|g')\n fi\n\n echo \"sudo pkgutil --only-files --files \\\"$PKGID\\\" | sed \\\"s|^|${FULL_INSTALL_LOCATION}/|\\\" | tr '\\\\\\\\n' '\\\\\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\"\n sudo pkgutil --only-files --files \"$PKGID\" | sed \"s|^|/${INSTALL_LOCATION}/|\" | tr '\\n' '\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\n\n echo \"sudo pkgutil --only-dirs --files \\\"$PKGID\\\" | sed \\\"s|^|${FULL_INSTALL_LOCATION}/|\\\" | grep '\\\\.app$' | tr '\\\\\\\\n' '\\\\\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\"\n sudo pkgutil --only-dirs --files \"$PKGID\" | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" | grep '\\.app$' | tr '\\n' '\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\n\n root_app_dir=$(\n sudo pkgutil --only-dirs --files \"$PKGID\" \\\n | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" \\\n | grep 'Applications' \\\n | awk '{ print length, $0 }' \\\n | sort -n \\\n | head -n1 \\\n | cut -d' ' -f2-\n )\n if [ -n \"$root_app_dir\" ]; then\n echo \"sudo rmdir -p \\\"$root_app_dir\\\" 2>/dev/null || :\"\n sudo rmdir -p \"$root_app_dir\" 2>/dev/null || :\n fi\n}\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nremove_launchctl_service 'com.microsoft.office.licensingV2.helper'\nquit_application 'com.microsoft.autoupdate2'\nremove_pkg_files 'com.microsoft.package.Microsoft_Word.app'\nforget_pkg 'com.microsoft.package.Microsoft_Word.app'\nremove_pkg_files 'com.microsoft.pkg.licensing'\nforget_pkg 'com.microsoft.pkg.licensing'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.microsoft.Word'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.microsoft.word.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/CrashReporter/Microsoft Word_*.plist'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.microsoft.Word'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.microsoft.Word.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.microsoft.Word.savedState'\n",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find the file and extract the embedded bash payload around quit_application
FILE="ee/maintained-apps/outputs/microsoft-word/darwin.json"
echo "== Checking $FILE exists =="
ls -la "$FILE"

echo
echo "== Extracting quit_application function block (context) =="
# Use python to parse JSON and extract the value of the big script by key (looks like "6d6819ed")
python3 - <<'PY'
import json, re
path="ee/maintained-apps/outputs/microsoft-word/darwin.json"
data=json.load(open(path))
key="6d6819ed"
s=data[key]
m=re.search(r'quit_application\s*\(\)\s*\{', s)
if not m:
    raise SystemExit("quit_application() not found")
start=m.start()
# print from start to a bit after function end (best-effort: until two newlines before next function)
# We'll just locate next "\n\nremove_launchctl_service" which follows in the provided snippet.
n=s.find("\n\nremove_launchctl_service", start)
print(s[start:n] if n!=-1 else s[start:start+2000])
PY

echo
echo "== Searching for other osascript 'application id ... is running' usage =="
rg -n "application id \\\\\\\"\\$?bundle_id\\\\\\\".*is running|is running\"|osascript -e \"application id .* is running" -S ee/maintained-apps/outputs/microsoft-word || true

echo
echo "== Searching for relaunch_application or install-related running checks across repo =="
rg -n "relaunch_application|tell application id.*to quit|app_running=.*osascript -e.*is running" -S ee/maintained-apps/outputs/microsoft-word || true

echo
echo "== Checking for any other uninstall payloads in same app directory with similar function =="
ls -ლა ee/maintained-apps/outputs/microsoft-word

Repository: fleetdm/fleet

Length of output: 409


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="ee/maintained-apps/outputs/microsoft-word/darwin.json"
echo "== Listing top-level keys in $FILE =="
python3 - <<'PY'
import json
path="ee/maintained-apps/outputs/microsoft-word/darwin.json"
data=json.load(open(path))
print("keys:", list(data.keys())[:50], "count=", len(data))
PY

echo
echo "== Locating quit_application() in the raw JSON payload (string content) =="
rg -n "quit_application\s*\(\)\s*\{" -n "$FILE" || true

echo
echo "== Showing the exact osascript 'is running' guard within quit_application() =="
python3 - <<'PY'
import json, re
path="ee/maintained-apps/outputs/microsoft-word/darwin.json"
data=json.load(open(path))

target_key=None
for k,v in data.items():
    if isinstance(v,str) and "quit_application()" in v and "application id" in v and "is running" in v:
        target_key=k
        break

if not target_key:
    # fallback: find any value containing quit_application
    for k,v in data.items():
        if isinstance(v,str) and "quit_application()" in v:
            target_key=k
            break

print("selected key:", target_key)

s=data[target_key]
m=re.search(r'quit_application\s*\(\)\s*\{', s)
if not m:
    raise SystemExit("quit_application() not found in selected payload")

start=m.start()
# take window after start
window=s[start:start+5000]

# print the first occurrence of the running check lines
mm=re.search(r'if\s+!\s+osascript\s+-e\s+"application id\\s+\\\\?"\\$bundle_id.*is running".*?fi', window, re.S)
if not mm:
    # print some lines around 'is running' occurrences
    idx=window.find("is running")
    print("window around 'is running':")
    print(window[max(0,idx-500):idx+500])
else:
    print("found running-check block:")
    print(mm.group(0))
PY

echo
echo "== Searching this file for any other output-comparison running checks =="
rg -n "app_running=.*osascript|!= \"true\"|=\\= \"true\"|is running" "$FILE" || true

Repository: fleetdm/fleet

Length of output: 6909


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search: any bash payloads in maintained-apps outputs using 'application id ... is running' =="
rg -n --hidden --no-ignore-vcs "osascript -e \"application id .* is running\"" ee/maintained-apps/outputs || true

echo
echo "== Search: output-comparison pattern for app_running !=/== 'true' =="
rg -n --hidden --no-ignore-vcs "app_running=.*osascript .*is running|\\[\\[ \\\"\\$app_running\\\" != \\\"true\\\"\\]\\]|\\[\\[ \\\"\\$app_running\\\" == \\\"true\\\"\\]\\]" ee/maintained-apps/outputs || true

echo
echo "== Search: any 'application id ... is running' checks anywhere else under ee/ =="
rg -n --hidden --no-ignore-vcs "application id .* is running" ee || true

echo
echo "== Search: literal guard form in uninstall payloads (guard uses exit status) =="
rg -n --hidden --no-ignore-vcs "if ! osascript -e \"application id .* is running\"" ee/maintained-apps/outputs || true

Repository: fleetdm/fleet

Length of output: 291


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="ee/maintained-apps/outputs/microsoft-word/darwin.json"

echo "== Locate payload id 6d6819ed occurrences in $FILE =="
rg -n "6d6819ed" "$FILE" || true

echo
echo "== Search this file for osascript 'application id ... is running' =="
rg -n "osascript -e \"application id .* is running\"" "$FILE" || true

echo
echo "== Search this file for the specific guard form that returns early =="
rg -n 'if ! osascript -e "application id .* is running"' "$FILE" || true

echo
echo "== Repo-wide search for the output-comparison form mentioned (literal text patterns) =="
rg -n --hidden --no-ignore-vcs --fixed-strings 'app_running=$(osascript' ee || true
rg -n --hidden --no-ignore-vcs --fixed-strings 'if [[ "$app_running" != "true" ]]' ee || true
rg -n --hidden --no-ignore-vcs --fixed-strings 'if [[ "$app_running" == "true" ]]' ee || true

echo
echo "== Repo-wide search for any 'application id ... is running' check =="
rg -n --hidden --no-ignore-vcs 'application id .* is running' ee || true

echo
echo "== Repo-wide search for the uninstall-style guard using exit status =="
rg -n --hidden --no-ignore-vcs 'if ! osascript -e "application id .* is running"' ee || true

Repository: fleetdm/fleet

Length of output: 50371


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Counting uninstall-style exit-status guards =="
rg -n --hidden --no-ignore-vcs 'if ! osascript -e "application id \\\".*\\\" is running"' ee/maintained-apps/outputs | head -n 50

echo
echo "== Also show any direct 'if ! osascript -e' with 'application id' =="
rg -n --hidden --no-ignore-vcs 'if ! osascript -e "application id' ee/maintained-apps/outputs | head -n 50

Repository: fleetdm/fleet

Length of output: 284


🏁 Script executed:

#!/bin/bash
set -euo pipefail

ROOT="ee/maintained-apps/outputs"

echo "== Exit-status guard form: if ! osascript -e \"application id ... is running\" =="
rg -n -F 'if ! osascript -e \"application id' "$ROOT" | head -n 50
echo
rg -n -F 'if ! osascript -e \"application id' "$ROOT" | wc -l

echo
echo "== Output-comparison form: app_running=$(osascript -e \"application id ... is running\" =="
rg -n -F 'app_running=$(osascript -e \"application id' "$ROOT" | head -n 50
echo
rg -n -F 'app_running=$(osascript -e \"application id' "$ROOT" | wc -l

Repository: fleetdm/fleet

Length of output: 48005


🏁 Script executed:

#!/bin/bash
set -euo pipefail
ROOT="ee/maintained-apps/outputs"

echo "== Count output-comparison running checks (app_running=$(osascript ... is running)) =="
rg -n -F 'app_running=$(osascript -e "application id' "$ROOT" | wc -l

echo "== Sample files using output-comparison form =="
rg -n -F 'app_running=$(osascript -e "application id' "$ROOT" | cut -d: -f1 | sort -u | head -n 20

Repository: fleetdm/fleet

Length of output: 185


🌐 Web query:

macOS osascript exit code behavior when expression evaluates to false

💡 Result:

The osascript command does not map the boolean result of an evaluated expression within an AppleScript to its own exit code [1][2]. When you run a script via osascript, the exit code of the command reflects the success or failure of the execution process itself, not the logic contained within the script [1][2]. Specifically: - If the script executes successfully (including when an expression evaluates to false), osascript exits with a status code of 0 [1][3]. - If the script encounters a runtime error or crashes, osascript typically exits with a non-zero status code (often 1) [4][5][6]. To influence the exit code of the shell process running osascript based on internal script logic, you cannot rely on returning a boolean value [1]. Instead, you must trigger an explicit error within your AppleScript using the error statement [4][1][3]. For example: osascript -e 'if false then return true else error "Condition failed" number 1' In this scenario, if the error statement is reached, osascript will exit with a non-zero status [1][3]. Note that error messages are printed to stderr by default [6][7], which can be managed using redirection (e.g., 2> /dev/null) or the -s o option to redirect them to stdout if needed for processing [4][5][8].

Citations:


Fix quit_application “is running” guard in Microsoft Word uninstall payload

ee/maintained-apps/outputs/microsoft-word/darwin.json (payload 6d6819ed) uses:

if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
  return
fi

This guard relies on osascript exit status; osascript returns exit code 0 even when the AppleScript evaluates to false, so this won’t early-return for non-running apps (it only returns on osascript execution errors). Other payloads in this repo capture stdout (app_running=...) and compare to "true".

🐛 Restore intended behavior
-  # check if the application is running
-  if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
-    return
-  fi
+  # check if the application is running
+  local app_running
+  app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+  if [[ "$app_running" != "true" ]]; then
+    return
+  fi
🤖 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/microsoft-word/darwin.json` at line 19, The
quit_application function's early-return guard uses osascript exit status which
is always 0 even when the script evaluates to false; change it to capture
osascript stdout (e.g., app_running=$(osascript -e "application id
\"$bundle_id\" is running" 2>/dev/null)) and then explicitly check if
app_running == "true" before proceeding (return when not "true"); update the
reference in quit_application where bundle_id is used and preserve the existing
stderr redirection.

@allenhouchins
allenhouchins merged commit 1ba5e05 into main Jun 3, 2026
13 checks passed
@allenhouchins
allenhouchins deleted the fma-2606030033 branch June 3, 2026 01:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants