Skip to content

Update Fleet-maintained apps - #48888

Closed
fleet-release wants to merge 1 commit into
mainfrom
fma-2607071858
Closed

Update Fleet-maintained apps#48888
fleet-release wants to merge 1 commit into
mainfrom
fma-2607071858

Conversation

@fleet-release

@fleet-release fleet-release commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Automated ingestion of latest Fleet-maintained app data.

Summary by CodeRabbit

  • Bug Fixes
    • Updated many app entries to newer releases across macOS and Windows, including Firefox, Docker Desktop, Postman, Microsoft Office apps, Bitwig Studio, KNIME, Zotero, and more.
    • Refreshed installer links, version checks, and package checksums so installs and update detection work with the latest available builds.
    • Adjusted a few uninstall/install behaviors for select apps to match their newer packaging.

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

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Script Diff Results

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

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

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

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

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

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

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

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

ee/maintained-apps/outputs/bitwig-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/dbvisualizer/darwin.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/dockside/darwin.json

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

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

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

ee/maintained-apps/outputs/elgato-wave-link/darwin.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/forklift/darwin.json

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

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

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

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

=== Install // c72d935a -> 3c077491 ===

--- /tmp/old.6IHkLb	2026-07-07 19:03:44.482959430 +0000
+++ /tmp/new.B7AU3J	2026-07-07 19:03:44.482959430 +0000
@@ -101,8 +101,8 @@
 hdiutil detach "$MOUNT_POINT" || true
 # copy to the applications folder
 quit_and_track_application 'org.knime.product'
-if [ -d "$APPDIR/KNIME 5.8.3.app" ]; then
-	sudo mv "$APPDIR/KNIME 5.8.3.app" "$TMPDIR/KNIME 5.8.3.app.bkp"
+if [ -d "$APPDIR/KNIME 5.12.0.app" ]; then
+	sudo mv "$APPDIR/KNIME 5.12.0.app" "$TMPDIR/KNIME 5.12.0.app.bkp"
 fi
-sudo cp -R "$TMPDIR/KNIME 5.8.3.app" "$APPDIR"
+sudo cp -R "$TMPDIR/KNIME 5.12.0.app" "$APPDIR"
 relaunch_application 'org.knime.product'

=== Uninstall // cb0b822a -> c9b745d8 ===

--- /tmp/old.j2lh8z	2026-07-07 19:03:44.496959443 +0000
+++ /tmp/new.fkeLlR	2026-07-07 19:03:44.496959443 +0000
@@ -52,7 +52,7 @@
   fi
 }
 
-sudo rm -rf "$APPDIR/KNIME 5.8.3.app"
+sudo rm -rf "$APPDIR/KNIME 5.12.0.app"
 trash $LOGGED_IN_USER '~/Library/Caches/org.knime.product'
 trash $LOGGED_IN_USER '~/Library/Preferences/org.knime.product.plist'
 trash $LOGGED_IN_USER '~/Library/Saved Application State/org.knime.product.savedState'

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

=== Install Script (no changes) ===
=== Uninstall // 39171b71 -> 02f458b9 ===

--- /tmp/old.RsDuwK	2026-07-07 19:03:44.533959477 +0000
+++ /tmp/new.lwoZUi	2026-07-07 19:03:44.533959477 +0000
@@ -54,6 +54,8 @@
 
 sudo rm -rf "$APPDIR/massCode.app"
 sudo rmdir '~/massCode'
-trash $LOGGED_IN_USER '~/Library/Application Support/massCode'
+trash $LOGGED_IN_USER '~/.massCode'
+trash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/io.masscode.app.sfl*'
+trash $LOGGED_IN_USER '~/Library/Application Support/masscode'
 trash $LOGGED_IN_USER '~/Library/Preferences/io.masscode.app.plist'
 trash $LOGGED_IN_USER '~/Library/Saved Application State/io.masscode.app.savedState'

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

=== Install // eb617288 -> 8dd8cff8 ===

--- /tmp/old.ALh7Lu	2026-07-07 19:03:44.573959514 +0000
+++ /tmp/new.hKI1Jj	2026-07-07 19:03:44.573959514 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.110.26062818_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Excel'

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

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

=== Install // 4a7cc8ae -> fc3e906d ===

--- /tmp/old.fdBbnu	2026-07-07 19:03:44.618959555 +0000
+++ /tmp/new.LfLj7R	2026-07-07 19:03:44.618959555 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.110.26062818_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Powerpoint'

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

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

=== Install // 481e55cb -> 3adefd29 ===

--- /tmp/old.8suiP4	2026-07-07 19:03:44.660959594 +0000
+++ /tmp/new.6sLxw9	2026-07-07 19:03:44.660959594 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.110.26062818_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Word'

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

ee/maintained-apps/outputs/musescore/darwin.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/origami-studio/darwin.json

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

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

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

ee/maintained-apps/outputs/portfolioperformance/windows.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/proton-pass/darwin.json

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

ee/maintained-apps/outputs/runjs/darwin.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/stats/darwin.json

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

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

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

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

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

ee/maintained-apps/outputs/webcatalog/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/worksheet-crafter/darwin.json

=== Install // 545289c7 -> 9be99456 ===

--- /tmp/old.NgJKDh	2026-07-07 19:03:45.225960115 +0000
+++ /tmp/new.m1RzLi	2026-07-07 19:03:45.225960115 +0000
@@ -96,5 +96,5 @@
 
 # install pkg files
 quit_and_track_application 'com.SchoolCraft.WillBeReplacedByQMake'
-sudo installer -pkg "$TMPDIR/worksheet-crafter_2026.2.4.pkg" -target /
+sudo installer -pkg "$TMPDIR/worksheet-crafter_2026.2.11.pkg" -target /
 relaunch_application 'com.SchoolCraft.WillBeReplacedByQMake'

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

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

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

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR updates Fleet-maintained app manifest JSON files across ee/maintained-apps/outputs for numerous macOS and Windows applications. Changes bump version numbers, update queries.patched version-comparison thresholds, replace installer_url download paths, and update sha256 checksums. For several apps (Knime, MassCode, Microsoft Excel/Word/PowerPoint, Worksheet Crafter), install_script_ref and/or uninstall_script_ref values were also updated, with corresponding embedded bash scripts in the refs map replaced or modified.

Changes

Cohort / Layer Changes
Simple version bumps Version, patched threshold, installer_url, and sha256 updates for AdGuard, Aptakube, Bezel, Bitrix24, Bitwig Studio, Claude, DBVisualizer, Docker, Dockside, Element, Elgato Wave Link, Firefox, ForkLift, Hive, MuseScore, OpenCode Desktop, Origami Studio, PortfolioPerformance, Postman, Proton Pass, RunJS, Shapr3D, Stats, Telegram, VSCodium, WebCatalog, WhatsApp, Zotero
Script ref rotation Knime, MassCode, Microsoft Excel/Word/PowerPoint, and Worksheet Crafter updates including install/uninstall script reference changes and embedded script content updates

Sequence Diagram(s)

Not applicable — this PR consists of data-only manifest updates without new control flow.

Possibly related PRs

  • fleetdm/fleet#48551: Updates the same WhatsApp darwin.json version and queries.patched threshold.
  • fleetdm/fleet#47971: Updates the same Microsoft Excel/Word/PowerPoint darwin.json entries including installer URLs and script refs.
  • fleetdm/fleet#48548: Updates the same Aptakube Windows manifest version, installer_url, and sha256.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is related to the changes, but it is very broad and does not identify the main update theme or affected apps. Rename it to mention the specific maintained-app metadata refresh or the key app/version updates, not just a generic update.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fma-2607071858

Warning

Tools execution failed with the following error:

Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


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

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 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/masscode/darwin.json`:
- Line 19: The cleanup script has a bad `sudo rmdir` invocation in the
`trash()`-based uninstall flow: `'~/massCode'` is quoted so bash will not expand
the tilde, causing the directory removal to target the wrong path. Update the
`masscode/darwin.json` uninstall command sequence to use the existing
`trash(logged_in_user, target_file)` pattern (or otherwise pass an unquoted
home-relative path that expands correctly) for `~/massCode`, matching the other
cleanup entries and keeping the `trash` helper as the single path-handling path.
🪄 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: df089fa2-e5a6-4f6c-b9ea-7831d2375604

📥 Commits

Reviewing files that changed from the base of the PR and between ceeaf9e and 0e97943.

📒 Files selected for processing (36)
  • ee/maintained-apps/outputs/adguard/darwin.json
  • ee/maintained-apps/outputs/aptakube/windows.json
  • ee/maintained-apps/outputs/bezel/darwin.json
  • ee/maintained-apps/outputs/bitrix24/darwin.json
  • ee/maintained-apps/outputs/bitwig-studio/darwin.json
  • ee/maintained-apps/outputs/claude/darwin.json
  • ee/maintained-apps/outputs/dbvisualizer/darwin.json
  • ee/maintained-apps/outputs/docker/windows.json
  • ee/maintained-apps/outputs/dockside/darwin.json
  • ee/maintained-apps/outputs/element/darwin.json
  • ee/maintained-apps/outputs/elgato-wave-link/darwin.json
  • ee/maintained-apps/outputs/firefox/darwin.json
  • ee/maintained-apps/outputs/forklift/darwin.json
  • ee/maintained-apps/outputs/hive-app/darwin.json
  • ee/maintained-apps/outputs/knime/darwin.json
  • ee/maintained-apps/outputs/masscode/darwin.json
  • ee/maintained-apps/outputs/microsoft-excel/darwin.json
  • ee/maintained-apps/outputs/microsoft-powerpoint/darwin.json
  • ee/maintained-apps/outputs/microsoft-word/darwin.json
  • ee/maintained-apps/outputs/musescore/darwin.json
  • ee/maintained-apps/outputs/opencode-desktop/darwin.json
  • ee/maintained-apps/outputs/origami-studio/darwin.json
  • ee/maintained-apps/outputs/portfolioperformance/darwin.json
  • ee/maintained-apps/outputs/portfolioperformance/windows.json
  • ee/maintained-apps/outputs/postman/darwin.json
  • ee/maintained-apps/outputs/postman/windows.json
  • ee/maintained-apps/outputs/proton-pass/darwin.json
  • ee/maintained-apps/outputs/runjs/darwin.json
  • ee/maintained-apps/outputs/shapr3d/darwin.json
  • ee/maintained-apps/outputs/stats/darwin.json
  • ee/maintained-apps/outputs/telegram/darwin.json
  • ee/maintained-apps/outputs/vscodium/darwin.json
  • ee/maintained-apps/outputs/webcatalog/darwin.json
  • ee/maintained-apps/outputs/whatsapp/darwin.json
  • ee/maintained-apps/outputs/worksheet-crafter/darwin.json
  • ee/maintained-apps/outputs/zotero/darwin.json

"refs": {
"0a664ca4": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'io.masscode.app'\nif [ -d \"$APPDIR/massCode.app\" ]; then\n\tsudo mv \"$APPDIR/massCode.app\" \"$TMPDIR/massCode.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/massCode.app\" \"$APPDIR\"\nrelaunch_application 'io.masscode.app'\n",
"39171b71": "#!/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/massCode.app\"\nsudo rmdir '~/massCode'\ntrash $LOGGED_IN_USER '~/Library/Application Support/massCode'\ntrash $LOGGED_IN_USER '~/Library/Preferences/io.masscode.app.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/io.masscode.app.savedState'\n"
"02f458b9": "#!/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/massCode.app\"\nsudo rmdir '~/massCode'\ntrash $LOGGED_IN_USER '~/.massCode'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/io.masscode.app.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/masscode'\ntrash $LOGGED_IN_USER '~/Library/Preferences/io.masscode.app.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/io.masscode.app.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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

# First, locate and read the file
fd -t f "darwin.json" | grep masscode | head -5

Repository: fleetdm/fleet

Length of output: 1949


🏁 Script executed:

# Check if file exists and read relevant content
if [ -f "ee/maintained-apps/outputs/masscode/darwin.json" ]; then
  head -100 "ee/maintained-apps/outputs/masscode/darwin.json"
fi

Repository: fleetdm/fleet

Length of output: 1949


🏁 Script executed:

# Verify bash behavior: tilde expansion in single vs double quotes
python3 - <<'PY'
import subprocess
import json

# Test bash tilde expansion behavior
test_cases = [
    ("echo '~/test'", "Single quotes - no expansion"),
    ('echo "~/test"', "Double quotes - no direct expansion"),
    ("echo ~/test", "Unquoted - expansion"),
]

print("=== Bash Tilde Expansion Behavior ===\n")
for cmd, desc in test_cases:
    result = subprocess.run(["bash", "-c", cmd], capture_output=True, text=True)
    print(f"{desc}:")
    print(f"  Command: {cmd}")
    print(f"  Output: {result.stdout.strip()}\n")

# Now test the actual problematic rmdir command behavior
print("=== Testing rmdir with literal '~/massCode' ===")
result = subprocess.run(
    ["bash", "-c", "rmdir '~/massCode' 2>&1"],
    capture_output=True,
    text=True,
)
print(f"Command: rmdir '~/massCode'")
print(f"Return code: {result.returncode}")
print(f"Output/Error: {result.stderr if result.stderr else result.stdout}")
PY

Repository: fleetdm/fleet

Length of output: 1949


🌐 Web query:

bash tilde expansion single quotes vs double quotes

💡 Result:

In Bash, tilde expansion does not occur when the tilde character is quoted, regardless of whether single or double quotes are used [1][2][3]. Tilde expansion is a shell feature that replaces a tilde-prefix (such as ) with a corresponding directory, typically the user's home directory [4][5]. For this expansion to take place, the tilde character must be unquoted [4][3]. If you place a path inside either single quotes ('') or double quotes ("~"), the shell treats the tilde as a literal character rather than a special expansion symbol [2][3]. To use a path involving the home directory while still utilizing quotes for other parts of the path (such as to handle spaces), you have two primary options: 1. Keep the tilde outside the quotes: You can leave the tilde unquoted and quote the remainder of the path. For example: ~/"my folder/file.txt" [2]. 2. Use $HOME instead: The $HOME variable is a common and robust alternative that expands within double quotes. For example: "$HOME/my folder/file.txt" [2][6]. This behavior exists because the shell's expansion rules explicitly require the tilde-prefix to be unquoted for the expansion to trigger [4][5]. Quoting, in any form, suppresses this behavior [3].

Citations:


The sudo rmdir '~/massCode' command silently fails because the tilde is not expanded inside single quotes.

Single quotes prevent tilde expansion in bash—this line targets a literal relative path ~/massCode instead of the user's home directory. All other cleanup entries in this script correctly use the trash() helper function, which manually expands leading tildes; this line bypasses that helper and never removes the directory.

Proposed fix
-sudo rmdir '~/massCode'
+sudo rmdir "/Users/$LOGGED_IN_USER/massCode" 2>/dev/null || true
📝 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.

Suggested change
"02f458b9": "#!/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/massCode.app\"\nsudo rmdir '~/massCode'\ntrash $LOGGED_IN_USER '~/.massCode'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/io.masscode.app.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/masscode'\ntrash $LOGGED_IN_USER '~/Library/Preferences/io.masscode.app.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/io.masscode.app.savedState'\n",
sudo rm -rf "$APPDIR/massCode.app"
sudo rmdir "/Users/$LOGGED_IN_USER/massCode" 2>/dev/null || true
trash $LOGGED_IN_USER '~/.massCode'
🤖 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/masscode/darwin.json` at line 19, The cleanup
script has a bad `sudo rmdir` invocation in the `trash()`-based uninstall flow:
`'~/massCode'` is quoted so bash will not expand the tilde, causing the
directory removal to target the wrong path. Update the `masscode/darwin.json`
uninstall command sequence to use the existing `trash(logged_in_user,
target_file)` pattern (or otherwise pass an unquoted home-relative path that
expands correctly) for `~/massCode`, matching the other cleanup entries and
keeping the `trash` helper as the single path-handling path.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Closing in favor of #48903.

@github-actions github-actions Bot closed this Jul 7, 2026
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