Skip to content

Update Fleet-maintained apps - #49330

Closed
fleet-release wants to merge 6 commits into
mainfrom
fma-2607151224
Closed

Update Fleet-maintained apps#49330
fleet-release wants to merge 6 commits into
mainfrom
fma-2607151224

Conversation

@fleet-release

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

Copy link
Copy Markdown
Contributor

Automated ingestion of latest Fleet-maintained app data.

Summary by CodeRabbit

  • Bug Fixes

    • Improved the Windows Discord installer script to more reliably detect installation completion, prevent lingering installer/process locks, and return clearer success vs. timeout/failure results with added diagnostics.
  • Chores

    • Refreshed maintained app release metadata across macOS and Windows by updating version numbers, installer download URLs, and SHA-256 checksums for multiple apps (Affinity, Android Studio, Badgeify, bdash, Beeper, Cursor, Docker Desktop, Dropbox, Git, GitUp, Chrome Remote Desktop Host, Chrome, Gemini, dnGrep, Kiro, Excel, OneNote, PowerPoint, Word, Raycast, Reqable, SoundAnchor, TablePlus, UPDF, Vivaldi, Wavebox, WeChat).

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

Copy link
Copy Markdown
Contributor

Script Diff Results

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

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

ee/maintained-apps/outputs/android-studio/windows.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/bdash/darwin.json

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

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

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

ee/maintained-apps/outputs/chrome-remote-desktop-host/darwin.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/dngrep/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/dropbox/windows.json

=== Install Script (no changes) ===
=== Uninstall // cb543651 -> b8df2b6f ===

--- /tmp/old.OshC1l	2026-07-15 12:33:10.605504889 +0000
+++ /tmp/new.qIwvlx	2026-07-15 12:33:10.605504889 +0000
@@ -1,4 +1,4 @@
-$product_code = '{D222FC32-3F3D-5818-9C9E-F00102AE398D}'
+$product_code = '{3DCEFA4A-E4B4-5D5A-BB8F-9F5974FD4C61}'
 $timeoutSeconds = 300  # 5 minute timeout
 
 # Fleet uninstalls app using product code that's extracted on upload

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

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

ee/maintained-apps/outputs/gitup-app/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/kiro-cli/darwin.json

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

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

=== Install // 8dd8cff8 -> bf3091ce ===

--- /tmp/old.8LEVRf	2026-07-15 12:33:10.867505815 +0000
+++ /tmp/new.uUJ9Zj	2026-07-15 12:33:10.868505818 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Excel'

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

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

=== Install // 75461837 -> 1ea0c21a ===

--- /tmp/old.WDPckR	2026-07-15 12:33:10.927506027 +0000
+++ /tmp/new.p2Gaob	2026-07-15 12:33:10.927506027 +0000
@@ -96,5 +96,5 @@
 
 # install pkg files
 quit_and_track_application 'com.microsoft.onenote.mac'
-sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.110.26062818_Updater.pkg" -target /
+sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.111.26071325_Updater.pkg" -target /
 relaunch_application 'com.microsoft.onenote.mac'

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

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

=== Install // fc3e906d -> 3d670a63 ===

--- /tmp/old.tOUbln	2026-07-15 12:33:10.983506225 +0000
+++ /tmp/new.tVRJ8G	2026-07-15 12:33:10.983506225 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Powerpoint'

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

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

=== Install // 3adefd29 -> 9d9d3bd0 ===

--- /tmp/old.nCbWb4	2026-07-15 12:33:11.038506419 +0000
+++ /tmp/new.1l4BhM	2026-07-15 12:33:11.039506423 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Word'

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Updated maintained-app manifests to newer macOS and Windows releases, synchronizing versions, SQL checks, installer URLs, and SHA-256 checksums. Dropbox updates its uninstall reference and MSI product code. Microsoft Office installation references now target newer packages. The Discord installer now detects completion through uninstall registry markers, cleans up related processes, and reports diagnostics on failure.

Possibly related PRs

  • fleetdm/fleet#49324: Updates overlapping maintained-app manifests and release metadata fields.
  • fleetdm/fleet#49318: Performs similar version, query, installer URL, and checksum updates.
  • fleetdm/fleet#49271: Modifies the same Discord installer execution and completion-handling logic.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is only a one-line summary and omits the required issue link, checklist items, testing, and other template sections. Add the template sections, including Related issue, checklist items, Testing, and any applicable Database migrations or fleetd/orbit notes.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly reflects the main change: updating Fleet-maintained apps.
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-2607151224

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/microsoft-powerpoint/darwin.json`:
- Line 19: Update the installer flow in
ee/maintained-apps/outputs/microsoft-powerpoint/darwin.json:19-19 and
ee/maintained-apps/outputs/microsoft-word/darwin.json:19-19 to capture the sudo
installer status, remove CHOICE_XML, and exit immediately on failure so
relaunch_application is not called. Preserve successful installation behavior
and clean up the temporary choices file on both success and failure.
🪄 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: 9cfe13b5-7a5e-4349-a066-e47d43bd930d

📥 Commits

Reviewing files that changed from the base of the PR and between d514466 and c604ea4.

📒 Files selected for processing (29)
  • ee/maintained-apps/outputs/affinity/darwin.json
  • ee/maintained-apps/outputs/android-studio/windows.json
  • ee/maintained-apps/outputs/badgeify/darwin.json
  • ee/maintained-apps/outputs/bdash/darwin.json
  • ee/maintained-apps/outputs/beeper/darwin.json
  • ee/maintained-apps/outputs/chrome-remote-desktop-host/darwin.json
  • ee/maintained-apps/outputs/cursor/windows.json
  • ee/maintained-apps/outputs/discord/windows.json
  • ee/maintained-apps/outputs/dngrep/windows.json
  • ee/maintained-apps/outputs/docker/windows.json
  • ee/maintained-apps/outputs/dropbox/windows.json
  • ee/maintained-apps/outputs/git/windows.json
  • ee/maintained-apps/outputs/gitup-app/darwin.json
  • ee/maintained-apps/outputs/google-chrome/darwin.json
  • ee/maintained-apps/outputs/google-gemini/darwin.json
  • ee/maintained-apps/outputs/kiro-cli/darwin.json
  • ee/maintained-apps/outputs/microsoft-excel/darwin.json
  • ee/maintained-apps/outputs/microsoft-onenote/darwin.json
  • ee/maintained-apps/outputs/microsoft-powerpoint/darwin.json
  • ee/maintained-apps/outputs/microsoft-word/darwin.json
  • ee/maintained-apps/outputs/raycast/darwin.json
  • ee/maintained-apps/outputs/reqable/darwin.json
  • ee/maintained-apps/outputs/reqable/windows.json
  • ee/maintained-apps/outputs/soundanchor/darwin.json
  • ee/maintained-apps/outputs/tableplus/darwin.json
  • ee/maintained-apps/outputs/updf/darwin.json
  • ee/maintained-apps/outputs/vivaldi/darwin.json
  • ee/maintained-apps/outputs/wavebox/darwin.json
  • ee/maintained-apps/outputs/wechat/darwin.json

"refs": {
"f61145e4": "#!/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 local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; 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 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 # A wildcard label can't be used with launchctl or as a plist name, so expand\n # it to the labels of currently loaded services that match the pattern.\n local services=(\"$service\")\n if [[ \"$service\" == *\"*\"* ]]; then\n local regex\n # Escape regex metacharacters, turn '*' into '.*', and anchor the pattern so\n # it matches a full label rather than a substring.\n regex=$(printf '%s' \"$service\" | sed -e 's/[][(){}.^$+?|\\\\]/\\\\&/g' -e 's/\\*/.*/g')\n regex=\"^${regex}$\"\n services=()\n local id\n # Match every loaded job by label regardless of PID; launchctl list reports\n # loaded-but-not-running jobs with a \"-\" in the PID column.\n while read -r _ _ id; do\n [[ \"$id\" =~ $regex ]] && services+=(\"$id\")\n done < <(launchctl list 2>/dev/null | tail -n +2)\n if [[ ${#services[@]} -eq 0 ]]; then\n echo \"No loaded launchctl service matches ${service}\"\n return\n fi\n fi\n\n local service_label\n for service_label in \"${services[@]}\"; do\n for should_sudo in \"${booleans[@]}\"; do\n plist_status=$(launchctl list \"${service_label}\" 2>/dev/null)\n\n if [[ $plist_status == \\{* ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo launchctl remove \"${service_label}\"\n else\n launchctl remove \"${service_label}\"\n fi\n sleep 1\n fi\n\n paths=(\n \"/Library/LaunchAgents/${service_label}.plist\"\n \"/Library/LaunchDaemons/${service_label}.plist\"\n )\n\n # if not using sudo, prepend the home directory to the paths\n if [[ $should_sudo == \"false\" ]]; then\n for i in \"${!paths[@]}\"; do\n paths[i]=\"${HOME}${paths[i]}\"\n done\n fi\n\n for path in \"${paths[@]}\"; do\n if [[ -e \"$path\" ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo rm -f -- \"$path\"\n else\n rm -f -- \"$path\"\n fi\n fi\n done\n done\n done\n}\n\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\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nremove_launchctl_service 'com.microsoft.office.licensingV2.helper'\nquit_application 'com.microsoft.autoupdate2'\nremove_pkg_files 'com.microsoft.package.Microsoft_PowerPoint.app'\nforget_pkg 'com.microsoft.package.Microsoft_PowerPoint.app'\nremove_pkg_files 'com.microsoft.pkg.licensing'\nforget_pkg 'com.microsoft.pkg.licensing'\nsudo rm -rf '/Applications/Microsoft PowerPoint.app'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.microsoft.Powerpoint*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.microsoft.powerpoint.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.microsoft.Powerpoint*'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.microsoft.Powerpoint.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.microsoft.Powerpoint.savedState'\n",
"fc3e906d": "#!/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.Powerpoint'\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_PowerPoint_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML \"$CHOICE_XML\"\n\nrelaunch_application 'com.microsoft.Powerpoint'\n"
"3d670a63": "#!/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.Powerpoint'\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_PowerPoint_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML \"$CHOICE_XML\"\n\nrelaunch_application 'com.microsoft.Powerpoint'\n",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not mask package-installation failures.

Both installers continue into relaunch logic without checking sudo installer:

  • ee/maintained-apps/outputs/microsoft-powerpoint/darwin.json#L19-L19: exit immediately on installer failure and clean up the temporary choices file.
  • ee/maintained-apps/outputs/microsoft-word/darwin.json#L19-L19: apply the same failure propagation.
📍 Affects 2 files
  • ee/maintained-apps/outputs/microsoft-powerpoint/darwin.json#L19-L19 (this comment)
  • ee/maintained-apps/outputs/microsoft-word/darwin.json#L19-L19
🤖 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-powerpoint/darwin.json` at line 19,
Update the installer flow in
ee/maintained-apps/outputs/microsoft-powerpoint/darwin.json:19-19 and
ee/maintained-apps/outputs/microsoft-word/darwin.json:19-19 to capture the sudo
installer status, remove CHOICE_XML, and exit immediately on failure so
relaunch_application is not called. Preserve successful installation behavior
and clean up the temporary choices file on both success and failure.

@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

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

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

ee/maintained-apps/outputs/android-studio/windows.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/bdash/darwin.json

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

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

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

ee/maintained-apps/outputs/chrome-remote-desktop-host/darwin.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/dngrep/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/dropbox/windows.json

=== Install Script (no changes) ===
=== Uninstall // cb543651 -> b8df2b6f ===

--- /tmp/old.gioyOW	2026-07-15 15:18:12.362919572 +0000
+++ /tmp/new.XOuYyF	2026-07-15 15:18:12.362919572 +0000
@@ -1,4 +1,4 @@
-$product_code = '{D222FC32-3F3D-5818-9C9E-F00102AE398D}'
+$product_code = '{3DCEFA4A-E4B4-5D5A-BB8F-9F5974FD4C61}'
 $timeoutSeconds = 300  # 5 minute timeout
 
 # Fleet uninstalls app using product code that's extracted on upload

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

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

ee/maintained-apps/outputs/gitup-app/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/kiro-cli/darwin.json

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

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

=== Install // 8dd8cff8 -> bf3091ce ===

--- /tmp/old.iRIYeD	2026-07-15 15:18:12.589920268 +0000
+++ /tmp/new.2EHzM5	2026-07-15 15:18:12.589920268 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Excel'

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

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

=== Install // 75461837 -> 1ea0c21a ===

--- /tmp/old.Ob9WUf	2026-07-15 15:18:12.643920434 +0000
+++ /tmp/new.QmTxvR	2026-07-15 15:18:12.643920434 +0000
@@ -96,5 +96,5 @@
 
 # install pkg files
 quit_and_track_application 'com.microsoft.onenote.mac'
-sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.110.26062818_Updater.pkg" -target /
+sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.111.26071325_Updater.pkg" -target /
 relaunch_application 'com.microsoft.onenote.mac'

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

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

=== Install // fc3e906d -> 3d670a63 ===

--- /tmp/old.osGLre	2026-07-15 15:18:12.694920594 +0000
+++ /tmp/new.5HwDvU	2026-07-15 15:18:12.694920594 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Powerpoint'

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

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

=== Install // 3adefd29 -> 9d9d3bd0 ===

--- /tmp/old.AIDqW1	2026-07-15 15:18:12.744920752 +0000
+++ /tmp/new.mbd1IA	2026-07-15 15:18:12.744920752 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Word'

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Discord uses a Squirrel-based installer that launches the app while keeping the setup stub resident. Blocking on Start-Process -Wait never returns, and the lingering DiscordSetup.exe locks its own file, breaking cleanup.

Replace the wait-based approach with non-blocking installation that polls the HKCU registry until Discord registers (5-minute timeout), then terminates all Discord processes to release file handles. This prevents hangs and allows proper cleanup.
@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

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

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

ee/maintained-apps/outputs/android-studio/windows.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/bdash/darwin.json

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

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

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

ee/maintained-apps/outputs/chrome-remote-desktop-host/darwin.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 // fd04e860 -> 1f796776 ===

--- /tmp/old.pgqFNc	2026-07-15 15:27:01.134032438 +0000
+++ /tmp/new.D3DfbU	2026-07-15 15:27:01.135032436 +0000
@@ -3,27 +3,48 @@
 
 $exeFilePath = "${env:INSTALLER_PATH}"
 
+# Discord ships a Squirrel-based installer. DiscordSetup.exe installs per-user to
+# %LOCALAPPDATA%\Discord, writes an uninstall entry to HKCU, and then LAUNCHES
+# Discord while the setup stub itself stays resident. Blocking on
+# Start-Process -Wait therefore never returns (it hangs until the harness kills
+# it), and the still-running DiscordSetup.exe keeps its own file locked, which
+# breaks temp-directory cleanup. Instead: start it without waiting, poll the
+# HKCU uninstall key until the install registers, then stop the spawned
+# processes so no handles are left holding the installer file open.
+
+$displayName = "Discord"
+$publisher = "Discord Inc."
+$uninstallKey = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+$deadline = (Get-Date).AddMinutes(5)
+$registered = $false
+
 try {
+    Start-Process -FilePath "$exeFilePath" -ArgumentList "-s" | Out-Null
 
-# Add argument to install silently
-# Discord uses Squirrel installer (common for Electron apps)
-# Discord uses -s (lowercase) for silent installation
-$processOptions = @{
-  FilePath = "$exeFilePath"
-  ArgumentList = "-s"
-  PassThru = $true
-  Wait = $true
+    while ((Get-Date) -lt $deadline) {
+        $entry = Get-ChildItem $uninstallKey -ErrorAction SilentlyContinue |
+            ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |
+            Where-Object { $_.DisplayName -eq $displayName -and $_.Publisher -eq $publisher }
+        if ($entry) {
+            $registered = $true
+            break
+        }
+        Start-Sleep -Seconds 5
+    }
+} catch {
+    Write-Host "Error: $_"
 }
-    
-# Start process and track exit code
-$process = Start-Process @processOptions
-$exitCode = $process.ExitCode
-
-# Prints the exit code
-Write-Host "Install exit code: $exitCode"
-Exit $exitCode
 
-} catch {
-  Write-Host "Error: $_"
-  Exit 1
+# Stop the auto-launched app and the installer stub so they don't keep file
+# handles open (a running DiscordSetup.exe locks its own file, blocking cleanup).
+foreach ($name in @("Discord", "Update", "DiscordSetup")) {
+    Stop-Process -Name $name -Force -ErrorAction SilentlyContinue
 }
+
+if ($registered) {
+    Write-Host "Discord registered in HKCU."
+    Exit 0
+}
+
+Write-Host "Discord did not register within timeout."
+Exit 1

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

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

=== Install Script (no changes) ===
=== Uninstall // cb543651 -> b8df2b6f ===

--- /tmp/old.ypsj6X	2026-07-15 15:27:02.531029340 +0000
+++ /tmp/new.e4TTnk	2026-07-15 15:27:02.531029340 +0000
@@ -1,4 +1,4 @@
-$product_code = '{D222FC32-3F3D-5818-9C9E-F00102AE398D}'
+$product_code = '{3DCEFA4A-E4B4-5D5A-BB8F-9F5974FD4C61}'
 $timeoutSeconds = 300  # 5 minute timeout
 
 # Fleet uninstalls app using product code that's extracted on upload

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

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

ee/maintained-apps/outputs/gitup-app/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/kiro-cli/darwin.json

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

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

=== Install // 8dd8cff8 -> bf3091ce ===

--- /tmp/old.6OLq73	2026-07-15 15:27:02.763028826 +0000
+++ /tmp/new.uHa7RA	2026-07-15 15:27:02.763028826 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Excel'

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

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

=== Install // 75461837 -> 1ea0c21a ===

--- /tmp/old.Ol5FJK	2026-07-15 15:27:02.816028708 +0000
+++ /tmp/new.ersDmy	2026-07-15 15:27:02.816028708 +0000
@@ -96,5 +96,5 @@
 
 # install pkg files
 quit_and_track_application 'com.microsoft.onenote.mac'
-sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.110.26062818_Updater.pkg" -target /
+sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.111.26071325_Updater.pkg" -target /
 relaunch_application 'com.microsoft.onenote.mac'

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

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

=== Install // fc3e906d -> 3d670a63 ===

--- /tmp/old.ADSgIr	2026-07-15 15:27:02.868028593 +0000
+++ /tmp/new.Homyeu	2026-07-15 15:27:02.868028593 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Powerpoint'

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

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

=== Install // 3adefd29 -> 9d9d3bd0 ===

--- /tmp/old.NjWawF	2026-07-15 15:27:02.918028482 +0000
+++ /tmp/new.aYRZuN	2026-07-15 15:27:02.919028480 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Word'

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@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

🧹 Nitpick comments (1)
ee/maintained-apps/inputs/winget/scripts/discord_install.ps1 (1)

25-27: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Simplify the registry subkey query.

You can simplify the registry query and improve its efficiency by using the wildcard capability of Get-ItemProperty to query all subkeys directly, eliminating the need to pipe Get-ChildItem into ForEach-Object.

♻️ Proposed refactor
-        $entry = Get-ChildItem $uninstallKey -ErrorAction SilentlyContinue |
-            ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |
-            Where-Object { $_.DisplayName -eq $displayName -and $_.Publisher -eq $publisher }
+        $entry = Get-ItemProperty "$uninstallKey\*" -ErrorAction SilentlyContinue |
+            Where-Object { $_.DisplayName -eq $displayName -and $_.Publisher -eq $publisher }
🤖 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/inputs/winget/scripts/discord_install.ps1` around lines 25
- 27, Update the registry lookup that assigns $entry to call Get-ItemProperty
with a wildcard path covering all subkeys beneath $uninstallKey, removing the
Get-ChildItem and ForEach-Object pipeline while preserving the existing
DisplayName and Publisher filtering.
🤖 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/discord_install.ps1`:
- Around line 38-42: Update the process-cleanup loop in discord_install.ps1 to
avoid stopping every process named Update. Use Get-Process and filter candidates
so only processes whose name or executable path identifies Discord are
terminated, while preserving forced termination and silent handling for missing
processes.

---

Nitpick comments:
In `@ee/maintained-apps/inputs/winget/scripts/discord_install.ps1`:
- Around line 25-27: Update the registry lookup that assigns $entry to call
Get-ItemProperty with a wildcard path covering all subkeys beneath
$uninstallKey, removing the Get-ChildItem and ForEach-Object pipeline while
preserving the existing DisplayName and Publisher filtering.
🪄 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: 9511590d-4847-488b-b267-dbfc64a712e0

📥 Commits

Reviewing files that changed from the base of the PR and between c604ea4 and 073d5df.

📒 Files selected for processing (2)
  • ee/maintained-apps/inputs/winget/scripts/discord_install.ps1
  • ee/maintained-apps/outputs/discord/windows.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • ee/maintained-apps/outputs/discord/windows.json

Comment on lines +38 to +42
# Stop the auto-launched app and the installer stub so they don't keep file
# handles open (a running DiscordSetup.exe locks its own file, blocking cleanup).
foreach ($name in @("Discord", "Update", "DiscordSetup")) {
Stop-Process -Name $name -Force -ErrorAction SilentlyContinue
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Prevent terminating background updates for other Squirrel-based applications.

Killing all processes named Update is overly broad and risky. Update.exe is the standard executable name for Squirrel, an installer framework used by many popular applications (e.g., Slack, GitHub Desktop, WhatsApp, Postman). Indiscriminately stopping Update might kill a concurrent installation or update for another application, potentially leaving it corrupted.

Instead, use Get-Process to fetch the target processes and filter them so that only those with Discord in their name or path are terminated.

🔒️ Proposed fix to safely target Discord processes
-# Stop the auto-launched app and the installer stub so they don't keep file
-# handles open (a running DiscordSetup.exe locks its own file, blocking cleanup).
-foreach ($name in @("Discord", "Update", "DiscordSetup")) {
-    Stop-Process -Name $name -Force -ErrorAction SilentlyContinue
-}
+# Stop the auto-launched app and the installer stub so they don't keep file
+# handles open (a running DiscordSetup.exe locks its own file, blocking cleanup).
+Get-Process -Name "Discord", "Update", "DiscordSetup" -ErrorAction SilentlyContinue |
+    Where-Object { $_.Name -match "Discord" -or $_.Path -match "Discord" } |
+    Stop-Process -Force -ErrorAction SilentlyContinue
📝 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
# Stop the auto-launched app and the installer stub so they don't keep file
# handles open (a running DiscordSetup.exe locks its own file, blocking cleanup).
foreach ($name in @("Discord", "Update", "DiscordSetup")) {
Stop-Process -Name $name -Force -ErrorAction SilentlyContinue
}
# Stop the auto-launched app and the installer stub so they don't keep file
# handles open (a running DiscordSetup.exe locks its own file, blocking cleanup).
Get-Process -Name "Discord", "Update", "DiscordSetup" -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match "Discord" -or $_.Path -match "Discord" } |
Stop-Process -Force -ErrorAction SilentlyContinue
🤖 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/inputs/winget/scripts/discord_install.ps1` around lines 38
- 42, Update the process-cleanup loop in discord_install.ps1 to avoid stopping
every process named Update. Use Get-Process and filter candidates so only
processes whose name or executable path identifies Discord are terminated, while
preserving forced termination and silent handling for missing processes.

@github-actions

Copy link
Copy Markdown
Contributor

Closing in favor of #49347.

@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

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

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

ee/maintained-apps/outputs/android-studio/windows.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/bdash/darwin.json

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

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

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

ee/maintained-apps/outputs/chrome-remote-desktop-host/darwin.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 // fd04e860 -> 1f796776 ===

--- /tmp/old.QL93Tu	2026-07-15 16:40:20.911120045 +0000
+++ /tmp/new.TpqJKm	2026-07-15 16:40:20.911120045 +0000
@@ -3,27 +3,48 @@
 
 $exeFilePath = "${env:INSTALLER_PATH}"
 
+# Discord ships a Squirrel-based installer. DiscordSetup.exe installs per-user to
+# %LOCALAPPDATA%\Discord, writes an uninstall entry to HKCU, and then LAUNCHES
+# Discord while the setup stub itself stays resident. Blocking on
+# Start-Process -Wait therefore never returns (it hangs until the harness kills
+# it), and the still-running DiscordSetup.exe keeps its own file locked, which
+# breaks temp-directory cleanup. Instead: start it without waiting, poll the
+# HKCU uninstall key until the install registers, then stop the spawned
+# processes so no handles are left holding the installer file open.
+
+$displayName = "Discord"
+$publisher = "Discord Inc."
+$uninstallKey = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+$deadline = (Get-Date).AddMinutes(5)
+$registered = $false
+
 try {
+    Start-Process -FilePath "$exeFilePath" -ArgumentList "-s" | Out-Null
 
-# Add argument to install silently
-# Discord uses Squirrel installer (common for Electron apps)
-# Discord uses -s (lowercase) for silent installation
-$processOptions = @{
-  FilePath = "$exeFilePath"
-  ArgumentList = "-s"
-  PassThru = $true
-  Wait = $true
+    while ((Get-Date) -lt $deadline) {
+        $entry = Get-ChildItem $uninstallKey -ErrorAction SilentlyContinue |
+            ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |
+            Where-Object { $_.DisplayName -eq $displayName -and $_.Publisher -eq $publisher }
+        if ($entry) {
+            $registered = $true
+            break
+        }
+        Start-Sleep -Seconds 5
+    }
+} catch {
+    Write-Host "Error: $_"
 }
-    
-# Start process and track exit code
-$process = Start-Process @processOptions
-$exitCode = $process.ExitCode
-
-# Prints the exit code
-Write-Host "Install exit code: $exitCode"
-Exit $exitCode
 
-} catch {
-  Write-Host "Error: $_"
-  Exit 1
+# Stop the auto-launched app and the installer stub so they don't keep file
+# handles open (a running DiscordSetup.exe locks its own file, blocking cleanup).
+foreach ($name in @("Discord", "Update", "DiscordSetup")) {
+    Stop-Process -Name $name -Force -ErrorAction SilentlyContinue
 }
+
+if ($registered) {
+    Write-Host "Discord registered in HKCU."
+    Exit 0
+}
+
+Write-Host "Discord did not register within timeout."
+Exit 1

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

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

=== Install Script (no changes) ===
=== Uninstall // cb543651 -> b8df2b6f ===

--- /tmp/old.wgb80y	2026-07-15 16:40:21.038123363 +0000
+++ /tmp/new.57yu2G	2026-07-15 16:40:21.038123363 +0000
@@ -1,4 +1,4 @@
-$product_code = '{D222FC32-3F3D-5818-9C9E-F00102AE398D}'
+$product_code = '{3DCEFA4A-E4B4-5D5A-BB8F-9F5974FD4C61}'
 $timeoutSeconds = 300  # 5 minute timeout
 
 # Fleet uninstalls app using product code that's extracted on upload

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

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

ee/maintained-apps/outputs/gitup-app/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/kiro-cli/darwin.json

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

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

=== Install // 8dd8cff8 -> bf3091ce ===

--- /tmp/old.U2biWo	2026-07-15 16:40:21.284129789 +0000
+++ /tmp/new.V5B3T8	2026-07-15 16:40:21.284129789 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Excel'

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

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

=== Install // 75461837 -> 1ea0c21a ===

--- /tmp/old.aAPXjY	2026-07-15 16:40:21.341131278 +0000
+++ /tmp/new.0mZl6M	2026-07-15 16:40:21.341131278 +0000
@@ -96,5 +96,5 @@
 
 # install pkg files
 quit_and_track_application 'com.microsoft.onenote.mac'
-sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.110.26062818_Updater.pkg" -target /
+sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.111.26071325_Updater.pkg" -target /
 relaunch_application 'com.microsoft.onenote.mac'

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

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

=== Install // fc3e906d -> 3d670a63 ===

--- /tmp/old.evfyIc	2026-07-15 16:40:21.395132689 +0000
+++ /tmp/new.8zOhAL	2026-07-15 16:40:21.396132715 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Powerpoint'

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

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

=== Install // 3adefd29 -> 9d9d3bd0 ===

--- /tmp/old.AUwdeQ	2026-07-15 16:40:21.456134283 +0000
+++ /tmp/new.hAlJei	2026-07-15 16:40:21.456134283 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Word'

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

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

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

ee/maintained-apps/outputs/android-studio/windows.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/bdash/darwin.json

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

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

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

ee/maintained-apps/outputs/chrome-remote-desktop-host/darwin.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 // 1f796776 -> 63fc3114 ===

--- /tmp/old.mC3vLg	2026-07-15 17:03:51.769266169 +0000
+++ /tmp/new.nc1Qq1	2026-07-15 17:03:51.769266169 +0000
@@ -8,43 +8,83 @@
 # Discord while the setup stub itself stays resident. Blocking on
 # Start-Process -Wait therefore never returns (it hangs until the harness kills
 # it), and the still-running DiscordSetup.exe keeps its own file locked, which
-# breaks temp-directory cleanup. Instead: start it without waiting, poll the
-# HKCU uninstall key until the install registers, then stop the spawned
-# processes so no handles are left holding the installer file open.
-
-$displayName = "Discord"
-$publisher = "Discord Inc."
-$uninstallKey = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-$deadline = (Get-Date).AddMinutes(5)
-$registered = $false
-
-try {
-    Start-Process -FilePath "$exeFilePath" -ArgumentList "-s" | Out-Null
-
-    while ((Get-Date) -lt $deadline) {
-        $entry = Get-ChildItem $uninstallKey -ErrorAction SilentlyContinue |
+# breaks temp-directory cleanup. Instead: start it without waiting, poll for the
+# install to complete, then stop the spawned processes so no handle is left
+# holding the installer file open.
+
+$installDir = Join-Path $env:LOCALAPPDATA "Discord"
+$uninstallRoots = @(
+    "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
+    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
+    "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+)
+
+function Test-DiscordInstalled {
+    # Filesystem signal: Squirrel drops Update.exe and an app-<version> folder.
+    if (Test-Path (Join-Path $installDir "Update.exe")) { return $true }
+    if (Test-Path (Join-Path $installDir "app-*")) { return $true }
+    # Registry signal: the uninstall entry the programs table (and our uninstall
+    # script) key on. Discord registers per-user (HKCU) but check HKLM too.
+    foreach ($root in $uninstallRoots) {
+        $hit = Get-ChildItem $root -ErrorAction SilentlyContinue |
             ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |
-            Where-Object { $_.DisplayName -eq $displayName -and $_.Publisher -eq $publisher }
-        if ($entry) {
-            $registered = $true
-            break
-        }
-        Start-Sleep -Seconds 5
+            Where-Object { $_.DisplayName -like "Discord*" }
+        if ($hit) { return $true }
     }
+    return $false
+}
+
+$installer = $null
+try {
+    $installer = Start-Process -FilePath "$exeFilePath" -ArgumentList "-s" -PassThru
 } catch {
-    Write-Host "Error: $_"
+    Write-Host "Error starting installer: $_"
+    Exit 1
+}
+
+# Poll well under the harness's 10-minute script timeout so the diagnostics
+# below always get a chance to print on failure.
+$deadline = (Get-Date).AddMinutes(7)
+$installed = $false
+while ((Get-Date) -lt $deadline) {
+    if (Test-DiscordInstalled) { $installed = $true; break }
+    Start-Sleep -Seconds 5
 }
 
 # Stop the auto-launched app and the installer stub so they don't keep file
 # handles open (a running DiscordSetup.exe locks its own file, blocking cleanup).
+if ($installer -and -not $installer.HasExited) {
+    Stop-Process -Id $installer.Id -Force -ErrorAction SilentlyContinue
+}
 foreach ($name in @("Discord", "Update", "DiscordSetup")) {
     Stop-Process -Name $name -Force -ErrorAction SilentlyContinue
 }
 
-if ($registered) {
-    Write-Host "Discord registered in HKCU."
+if ($installed) {
+    Write-Host "Discord installed."
     Exit 0
 }
 
-Write-Host "Discord did not register within timeout."
+# Nothing detected: surface what actually happened so the failure is actionable
+# instead of a bare timeout.
+Write-Host "Discord did not install within timeout."
+if ($installer) {
+    if ($installer.HasExited) {
+        Write-Host "Installer process exit code: $($installer.ExitCode)"
+    } else {
+        Write-Host "Installer process was still running at timeout."
+    }
+}
+Write-Host "Install dir '$installDir' exists: $(Test-Path $installDir)"
+if (Test-Path $installDir) {
+    Get-ChildItem $installDir -ErrorAction SilentlyContinue |
+        Select-Object -ExpandProperty Name |
+        ForEach-Object { Write-Host "  $_" }
+}
+foreach ($root in $uninstallRoots) {
+    Get-ChildItem $root -ErrorAction SilentlyContinue |
+        ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |
+        Where-Object { $_.DisplayName -like "*iscord*" } |
+        ForEach-Object { Write-Host "Registry $root -> DisplayName='$($_.DisplayName)' Publisher='$($_.Publisher)'" }
+}
 Exit 1

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

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

=== Install Script (no changes) ===
=== Uninstall // cb543651 -> b8df2b6f ===

--- /tmp/old.E4qK2I	2026-07-15 17:03:51.859266447 +0000
+++ /tmp/new.TEXlK8	2026-07-15 17:03:51.859266447 +0000
@@ -1,4 +1,4 @@
-$product_code = '{D222FC32-3F3D-5818-9C9E-F00102AE398D}'
+$product_code = '{3DCEFA4A-E4B4-5D5A-BB8F-9F5974FD4C61}'
 $timeoutSeconds = 300  # 5 minute timeout
 
 # Fleet uninstalls app using product code that's extracted on upload

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

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

ee/maintained-apps/outputs/gitup-app/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/kiro-cli/darwin.json

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

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

=== Install // 8dd8cff8 -> bf3091ce ===

--- /tmp/old.M9CDnk	2026-07-15 17:03:52.068267093 +0000
+++ /tmp/new.7HSzlS	2026-07-15 17:03:52.068267093 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Excel'

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

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

=== Install // 75461837 -> 1ea0c21a ===

--- /tmp/old.SynhJp	2026-07-15 17:03:52.111267226 +0000
+++ /tmp/new.m3SFeh	2026-07-15 17:03:52.111267226 +0000
@@ -96,5 +96,5 @@
 
 # install pkg files
 quit_and_track_application 'com.microsoft.onenote.mac'
-sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.110.26062818_Updater.pkg" -target /
+sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.111.26071325_Updater.pkg" -target /
 relaunch_application 'com.microsoft.onenote.mac'

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

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

=== Install // fc3e906d -> 3d670a63 ===

--- /tmp/old.khilms	2026-07-15 17:03:52.153267356 +0000
+++ /tmp/new.bNXv2R	2026-07-15 17:03:52.153267356 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Powerpoint'

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

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

=== Install // 3adefd29 -> 9d9d3bd0 ===

--- /tmp/old.xGTkH0	2026-07-15 17:03:52.196267489 +0000
+++ /tmp/new.LwoBSw	2026-07-15 17:03:52.196267489 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Word'

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@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.

♻️ Duplicate comments (1)
ee/maintained-apps/inputs/winget/scripts/discord_install.ps1 (1)

54-61: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Prevent terminating background updates for other Squirrel-based applications.

Killing all processes named Update is overly broad and risky. Update.exe is the standard executable name for Squirrel, an installer framework used by many popular applications (e.g., Slack, GitHub Desktop, WhatsApp, Postman). Indiscriminately stopping Update might kill a concurrent installation or update for another application, potentially leaving it corrupted. Both the source script and the generated manifest share this hazard.

  • ee/maintained-apps/inputs/winget/scripts/discord_install.ps1#L54-L61: Update the process-cleanup loop to use Get-Process and filter candidates so only processes whose name or executable path identifies Discord are terminated.
  • ee/maintained-apps/outputs/discord/windows.json#L20-L20: Apply the same process filtering logic to the inline script payload (with proper JSON escaping).
🤖 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/inputs/winget/scripts/discord_install.ps1` around lines 54
- 61, Restrict the process cleanup loop in
ee/maintained-apps/inputs/winget/scripts/discord_install.ps1 (lines 54-61) to
Get-Process candidates whose process name or executable path identifies Discord,
rather than terminating every Update process; preserve cleanup of the Discord
and installer processes. Apply the same filtered logic, with correct JSON
escaping, to the inline payload in
ee/maintained-apps/outputs/discord/windows.json (line 20).
🤖 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.

Duplicate comments:
In `@ee/maintained-apps/inputs/winget/scripts/discord_install.ps1`:
- Around line 54-61: Restrict the process cleanup loop in
ee/maintained-apps/inputs/winget/scripts/discord_install.ps1 (lines 54-61) to
Get-Process candidates whose process name or executable path identifies Discord,
rather than terminating every Update process; preserve cleanup of the Discord
and installer processes. Apply the same filtered logic, with correct JSON
escaping, to the inline payload in
ee/maintained-apps/outputs/discord/windows.json (line 20).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 64ae0986-6818-4dd0-965e-aa3c81ece985

📥 Commits

Reviewing files that changed from the base of the PR and between 073d5df and 7db1231.

📒 Files selected for processing (2)
  • ee/maintained-apps/inputs/winget/scripts/discord_install.ps1
  • ee/maintained-apps/outputs/discord/windows.json

@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

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

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

ee/maintained-apps/outputs/android-studio/windows.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/bdash/darwin.json

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

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

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

ee/maintained-apps/outputs/chrome-remote-desktop-host/darwin.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 // 63fc3114 -> c3c80b80 ===

--- /tmp/old.mry1uH	2026-07-15 17:21:17.745063892 +0000
+++ /tmp/new.qwpwHy	2026-07-15 17:21:17.745063892 +0000
@@ -3,35 +3,35 @@
 
 $exeFilePath = "${env:INSTALLER_PATH}"
 
-# Discord ships a Squirrel-based installer. DiscordSetup.exe installs per-user to
+# Discord ships a Squirrel-based installer. DiscordSetup.exe extracts the app to
 # %LOCALAPPDATA%\Discord, writes an uninstall entry to HKCU, and then LAUNCHES
 # Discord while the setup stub itself stays resident. Blocking on
 # Start-Process -Wait therefore never returns (it hangs until the harness kills
 # it), and the still-running DiscordSetup.exe keeps its own file locked, which
-# breaks temp-directory cleanup. Instead: start it without waiting, poll for the
-# install to complete, then stop the spawned processes so no handle is left
+# breaks temp-directory cleanup.
+#
+# Poll for the uninstall REGISTRY entry, not the install directory: the app
+# folder appears early during extraction, so keying on it would let us kill the
+# installer before Squirrel finishes writing the registry entry that osquery's
+# programs table -- and Fleet's inventory -- rely on. Once the entry exists the
+# install is complete; then stop the spawned processes so no handle is left
 # holding the installer file open.
 
-$installDir = Join-Path $env:LOCALAPPDATA "Discord"
 $uninstallRoots = @(
     "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
     "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
     "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
 )
 
-function Test-DiscordInstalled {
-    # Filesystem signal: Squirrel drops Update.exe and an app-<version> folder.
-    if (Test-Path (Join-Path $installDir "Update.exe")) { return $true }
-    if (Test-Path (Join-Path $installDir "app-*")) { return $true }
-    # Registry signal: the uninstall entry the programs table (and our uninstall
-    # script) key on. Discord registers per-user (HKCU) but check HKLM too.
+function Get-DiscordUninstallEntry {
     foreach ($root in $uninstallRoots) {
         $hit = Get-ChildItem $root -ErrorAction SilentlyContinue |
             ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |
-            Where-Object { $_.DisplayName -like "Discord*" }
-        if ($hit) { return $true }
+            Where-Object { $_.DisplayName -like "Discord*" } |
+            Select-Object -First 1
+        if ($hit) { return $hit }
     }
-    return $false
+    return $null
 }
 
 $installer = $null
@@ -45,9 +45,10 @@
 # Poll well under the harness's 10-minute script timeout so the diagnostics
 # below always get a chance to print on failure.
 $deadline = (Get-Date).AddMinutes(7)
-$installed = $false
+$entry = $null
 while ((Get-Date) -lt $deadline) {
-    if (Test-DiscordInstalled) { $installed = $true; break }
+    $entry = Get-DiscordUninstallEntry
+    if ($entry) { break }
     Start-Sleep -Seconds 5
 }
 
@@ -60,14 +61,13 @@
     Stop-Process -Name $name -Force -ErrorAction SilentlyContinue
 }
 
-if ($installed) {
-    Write-Host "Discord installed."
+if ($entry) {
+    Write-Host "Discord registered: DisplayName='$($entry.DisplayName)' Version='$($entry.DisplayVersion)'"
     Exit 0
 }
 
-# Nothing detected: surface what actually happened so the failure is actionable
-# instead of a bare timeout.
-Write-Host "Discord did not install within timeout."
+# Nothing detected: surface what actually happened so the failure is actionable.
+Write-Host "Discord did not register within timeout."
 if ($installer) {
     if ($installer.HasExited) {
         Write-Host "Installer process exit code: $($installer.ExitCode)"
@@ -75,6 +75,7 @@
         Write-Host "Installer process was still running at timeout."
     }
 }
+$installDir = Join-Path $env:LOCALAPPDATA "Discord"
 Write-Host "Install dir '$installDir' exists: $(Test-Path $installDir)"
 if (Test-Path $installDir) {
     Get-ChildItem $installDir -ErrorAction SilentlyContinue |
@@ -85,6 +86,6 @@
     Get-ChildItem $root -ErrorAction SilentlyContinue |
         ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |
         Where-Object { $_.DisplayName -like "*iscord*" } |
-        ForEach-Object { Write-Host "Registry $root -> DisplayName='$($_.DisplayName)' Publisher='$($_.Publisher)'" }
+        ForEach-Object { Write-Host "Registry $root -> DisplayName='$($_.DisplayName)' Publisher='$($_.Publisher)' Version='$($_.DisplayVersion)'" }
 }
 Exit 1

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

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

=== Install Script (no changes) ===
=== Uninstall // cb543651 -> b8df2b6f ===

--- /tmp/old.rQx3vy	2026-07-15 17:21:17.835059770 +0000
+++ /tmp/new.YKKAhQ	2026-07-15 17:21:17.835059770 +0000
@@ -1,4 +1,4 @@
-$product_code = '{D222FC32-3F3D-5818-9C9E-F00102AE398D}'
+$product_code = '{3DCEFA4A-E4B4-5D5A-BB8F-9F5974FD4C61}'
 $timeoutSeconds = 300  # 5 minute timeout
 
 # Fleet uninstalls app using product code that's extracted on upload

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

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

ee/maintained-apps/outputs/gitup-app/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/kiro-cli/darwin.json

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

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

=== Install // 8dd8cff8 -> bf3091ce ===

--- /tmp/old.K9z3kh	2026-07-15 17:21:18.002052122 +0000
+++ /tmp/new.VUQcCd	2026-07-15 17:21:18.002052122 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Excel'

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

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

=== Install // 75461837 -> 1ea0c21a ===

--- /tmp/old.ocF1D3	2026-07-15 17:21:18.044050199 +0000
+++ /tmp/new.kp1l3T	2026-07-15 17:21:18.044050199 +0000
@@ -96,5 +96,5 @@
 
 # install pkg files
 quit_and_track_application 'com.microsoft.onenote.mac'
-sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.110.26062818_Updater.pkg" -target /
+sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.111.26071325_Updater.pkg" -target /
 relaunch_application 'com.microsoft.onenote.mac'

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

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

=== Install // fc3e906d -> 3d670a63 ===

--- /tmp/old.OCqe1H	2026-07-15 17:21:18.082048459 +0000
+++ /tmp/new.xLrh25	2026-07-15 17:21:18.082048459 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Powerpoint'

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

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

=== Install // 3adefd29 -> 9d9d3bd0 ===

--- /tmp/old.qc2j0r	2026-07-15 17:21:18.121046672 +0000
+++ /tmp/new.AHoAfK	2026-07-15 17:21:18.121046672 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Word'

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@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.

♻️ Duplicate comments (1)
ee/maintained-apps/inputs/winget/scripts/discord_install.ps1 (1)

60-62: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Prevent terminating background updates for other Squirrel-based applications.

Killing all processes named Update is overly broad and risky. Update.exe is the standard executable name for Squirrel, an installer framework used by many popular applications (e.g., Slack, GitHub Desktop). Indiscriminately stopping Update might kill a concurrent installation or update for another application, potentially leaving it corrupted.

Instead, use Get-Process to fetch the target processes and filter them so that only those with Discord in their name or path are terminated.

🔒️ Proposed fix to safely target Discord processes
-foreach ($name in @("Discord", "Update", "DiscordSetup")) {
-    Stop-Process -Name $name -Force -ErrorAction SilentlyContinue
-}
+Get-Process -Name "Discord", "Update", "DiscordSetup" -ErrorAction SilentlyContinue |
+    Where-Object { $_.Name -match "Discord" -or $_.Path -match "Discord" } |
+    Stop-Process -Force -ErrorAction SilentlyContinue
🤖 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/inputs/winget/scripts/discord_install.ps1` around lines 60
- 62, Update the process-termination loop in the Discord installation script to
stop only processes associated with Discord. Replace the broad `Update` name
match with `Get-Process` results filtered for a process name or executable path
containing `Discord`, then force-stop only those targets while preserving silent
handling for missing processes.
🤖 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.

Duplicate comments:
In `@ee/maintained-apps/inputs/winget/scripts/discord_install.ps1`:
- Around line 60-62: Update the process-termination loop in the Discord
installation script to stop only processes associated with Discord. Replace the
broad `Update` name match with `Get-Process` results filtered for a process name
or executable path containing `Discord`, then force-stop only those targets
while preserving silent handling for missing processes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f64a3067-fde9-4ca0-b331-b437f7b8a120

📥 Commits

Reviewing files that changed from the base of the PR and between 7db1231 and 4aeb7d8.

📒 Files selected for processing (2)
  • ee/maintained-apps/inputs/winget/scripts/discord_install.ps1
  • ee/maintained-apps/outputs/discord/windows.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • ee/maintained-apps/outputs/discord/windows.json

@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: 4

🤖 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/discord/windows.json`:
- Line 20: In the Discord installer timeout path, capture the installer’s
HasExited state and ExitCode before the Stop-Process cleanup block. Store these
values immediately before terminating $installer and related processes, then use
the saved values in the failure diagnostics instead of querying the process
afterward.
- Line 20: Update the process cleanup after the installer polling loop,
including the `$installer` handling and `foreach ($name ...)` block, so it only
stops processes spawned by this Discord installer invocation. Track or discover
the installer’s child process tree and validate each executable path before
termination; remove broad name-based kills that could affect existing Discord
sessions or unrelated `Update` processes.
- Line 20: Extend the timeout diagnostics after the Discord install-directory
check to also inspect %LOCALAPPDATA%\SquirrelTemp\SquirrelSetup.log. Read and
print its tail using the same existing logging pattern, while preserving the
current Discord\SquirrelSetup.log diagnostics and handling a missing
SquirrelTemp directory or log safely.
- Line 20: Update Get-DiscordUninstallEntry and the polling flow to identify the
newly installed target stable Discord version rather than accepting any existing
DisplayName matching “Discord*”. Capture the pre-install registry state or
validate the expected stable app/version, and only treat a matching new/current
entry as completion; preserve the existing timeout and diagnostics behavior
otherwise.
🪄 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: 7825529f-7126-4326-938f-ab885d9862de

📥 Commits

Reviewing files that changed from the base of the PR and between 4aeb7d8 and 0e5a646.

📒 Files selected for processing (2)
  • ee/maintained-apps/inputs/winget/scripts/discord_install.ps1
  • ee/maintained-apps/outputs/discord/windows.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • ee/maintained-apps/inputs/winget/scripts/discord_install.ps1

"refs": {
"73fc6eff": "# Attempts to locate Discord's uninstaller from registry and execute it silently\n\n$displayName = \"Discord\"\n$publisher = \"Discord Inc.\"\n\n$paths = @(\n 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',\n 'HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'\n)\n\n$uninstall = $null\nforeach ($p in $paths) {\n $items = Get-ItemProperty \"$p\\*\" -ErrorAction SilentlyContinue | Where-Object {\n $_.DisplayName -and ($_.DisplayName -eq $displayName -or $_.DisplayName -like \"$displayName*\") -and ($publisher -eq \"\" -or $_.Publisher -eq $publisher)\n }\n if ($items) { $uninstall = $items | Select-Object -First 1; break }\n}\n\nif (-not $uninstall -or -not $uninstall.UninstallString) {\n Write-Host \"Uninstall entry not found\"\n Exit 0\n}\n\n# Kill any running Discord processes before uninstalling\nStop-Process -Name \"Discord\" -Force -ErrorAction SilentlyContinue\n\n$uninstallString = $uninstall.UninstallString\n$exePath = \"\"\n$arguments = \"\"\n\n# Parse the uninstall string to extract executable path and existing arguments\n# Handles both quoted and unquoted paths\nif ($uninstallString -match '^\"([^\"]+)\"(.*)') {\n $exePath = $matches[1]\n $arguments = $matches[2].Trim()\n} elseif ($uninstallString -match '^([^\\s]+)(.*)') {\n $exePath = $matches[1]\n $arguments = $matches[2].Trim()\n} else {\n Write-Host \"Error: Could not parse uninstall string: $uninstallString\"\n Exit 1\n}\n\n# Build argument list array, preserving existing arguments and adding -s for silent\n$argumentList = @()\nif ($arguments -ne '') {\n # Split existing arguments and add them\n $argumentList += $arguments -split '\\s+'\n}\n$argumentList += \"-s\"\n\nWrite-Host \"Uninstall executable: $exePath\"\nWrite-Host \"Uninstall arguments: $($argumentList -join ' ')\"\n\ntry {\n $processOptions = @{\n FilePath = $exePath\n ArgumentList = $argumentList\n NoNewWindow = $true\n PassThru = $true\n Wait = $true\n }\n \n $process = Start-Process @processOptions\n $exitCode = $process.ExitCode\n \n Write-Host \"Uninstall exit code: $exitCode\"\n Exit $exitCode\n} catch {\n Write-Host \"Error running uninstaller: $_\"\n Exit 1\n}\n\n",
"fd04e860": "# 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# Add argument to install silently\n# Discord uses Squirrel installer (common for Electron apps)\n# Discord uses -s (lowercase) for silent installation\n$processOptions = @{\n FilePath = \"$exeFilePath\"\n ArgumentList = \"-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\n"
"6890f549": "# Learn more about .exe install scripts:\n# http://fleetdm.com/learn-more-about/exe-install-scripts\n\n$exeFilePath = \"${env:INSTALLER_PATH}\"\n\n# Discord ships a Squirrel-based installer. DiscordSetup.exe extracts the app to\n# %LOCALAPPDATA%\\Discord, writes an uninstall entry to HKCU, and then LAUNCHES\n# Discord while the setup stub itself stays resident. Blocking on\n# Start-Process -Wait therefore never returns (it hangs until the harness kills\n# it), and the still-running DiscordSetup.exe keeps its own file locked, which\n# breaks temp-directory cleanup.\n#\n# Poll for the uninstall REGISTRY entry, not the install directory: the app\n# folder appears early during extraction, so keying on it would let us kill the\n# installer before Squirrel finishes writing the registry entry that osquery's\n# programs table -- and Fleet's inventory -- rely on. Once the entry exists the\n# install is complete; then stop the spawned processes so no handle is left\n# holding the installer file open.\n\n$uninstallRoots = @(\n \"HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\",\n \"HKCU:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\",\n \"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\",\n \"HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\"\n)\n\nfunction Get-DiscordUninstallEntry {\n foreach ($root in $uninstallRoots) {\n $hit = Get-ChildItem $root -ErrorAction SilentlyContinue |\n ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |\n Where-Object { $_.DisplayName -like \"Discord*\" } |\n Select-Object -First 1\n if ($hit) { return $hit }\n }\n return $null\n}\n\n$installer = $null\ntry {\n $installer = Start-Process -FilePath \"$exeFilePath\" -ArgumentList \"-s\" -PassThru\n} catch {\n Write-Host \"Error starting installer: $_\"\n Exit 1\n}\n\n# Poll well under the harness's 10-minute script timeout so the diagnostics\n# below always get a chance to print on failure.\n$deadline = (Get-Date).AddMinutes(7)\n$entry = $null\nwhile ((Get-Date) -lt $deadline) {\n $entry = Get-DiscordUninstallEntry\n if ($entry) { break }\n Start-Sleep -Seconds 5\n}\n\n# Stop the auto-launched app and the installer stub so they don't keep file\n# handles open (a running DiscordSetup.exe locks its own file, blocking cleanup).\nif ($installer -and -not $installer.HasExited) {\n Stop-Process -Id $installer.Id -Force -ErrorAction SilentlyContinue\n}\nforeach ($name in @(\"Discord\", \"Update\", \"DiscordSetup\")) {\n Stop-Process -Name $name -Force -ErrorAction SilentlyContinue\n}\n\nif ($entry) {\n Write-Host \"Discord registered: DisplayName='$($entry.DisplayName)' Version='$($entry.DisplayVersion)'\"\n Exit 0\n}\n\n# Nothing detected: surface what actually happened so the failure is actionable.\nWrite-Host \"Discord did not register within timeout.\"\nif ($installer) {\n if ($installer.HasExited) {\n Write-Host \"Installer process exit code: $($installer.ExitCode)\"\n } else {\n Write-Host \"Installer process was still running at timeout.\"\n }\n}\n$installDir = Join-Path $env:LOCALAPPDATA \"Discord\"\nWrite-Host \"Install dir '$installDir' exists: $(Test-Path $installDir)\"\nif (Test-Path $installDir) {\n Get-ChildItem $installDir -ErrorAction SilentlyContinue |\n Select-Object -ExpandProperty Name |\n ForEach-Object { Write-Host \" $_\" }\n # SquirrelSetup.log records exactly what the installer did, including\n # whether/where it wrote the uninstall registry entry and why it exited.\n $squirrelLog = Join-Path $installDir \"SquirrelSetup.log\"\n if (Test-Path $squirrelLog) {\n Write-Host \"---- SquirrelSetup.log (tail) ----\"\n Get-Content $squirrelLog -Tail 50 -ErrorAction SilentlyContinue |\n ForEach-Object { Write-Host $_ }\n Write-Host \"---- end SquirrelSetup.log ----\"\n }\n}\nforeach ($root in $uninstallRoots) {\n Get-ChildItem $root -ErrorAction SilentlyContinue |\n ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |\n Where-Object { $_.DisplayName -like \"*iscord*\" } |\n ForEach-Object { Write-Host \"Registry $root -> DisplayName='$($_.DisplayName)' Publisher='$($_.Publisher)' Version='$($_.DisplayVersion)'\" }\n}\nExit 1\n"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Capture installer status before force-killing it.

The timeout path calls Stop-Process first, then checks HasExited and ExitCode. This loses the original timeout state and can report a forced termination as the installer’s exit result. Record HasExited and ExitCode before cleanup, then terminate processes.

🤖 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/discord/windows.json` at line 20, In the Discord
installer timeout path, capture the installer’s HasExited state and ExitCode
before the Stop-Process cleanup block. Store these values immediately before
terminating $installer and related processes, then use the saved values in the
failure diagnostics instead of querying the process afterward.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Scope process cleanup to the Discord installer tree.

Stop-Process -Name "Update" can terminate unrelated user processes, and the broad Discord/DiscordSetup name matching can disrupt an existing Discord session. Track the installer’s child processes or validate executable paths before terminating them; do not kill every process with a generic name.

🤖 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/discord/windows.json` at line 20, Update the
process cleanup after the installer polling loop, including the `$installer`
handling and `foreach ($name ...)` block, so it only stops processes spawned by
this Discord installer invocation. Track or discover the installer’s child
process tree and validate each executable path before termination; remove broad
name-based kills that could affect existing Discord sessions or unrelated
`Update` processes.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

set -euo pipefail
printf 'FILE:\n'
git ls-files ee/maintained-apps/outputs/discord/windows.json
printf '\nCONTEXT:\n'
cat -n ee/maintained-apps/outputs/discord/windows.json | sed -n '1,140p'
printf '\nSEARCH:\n'
rg -n "SquirrelTemp|SquirrelSetup\.log|DiscordSetup|Squirrel" ee/maintained-apps -S

Repository: fleetdm/fleet

Length of output: 45151


🌐 Web query:

SquirrelSetup.log SquirrelTemp log location LOCALAPPDATA

💡 Result:

The SquirrelSetup.log file is primarily located in the %LocalAppData%\SquirrelTemp directory [1][2][3]. This location is used by the Squirrel installer (commonly utilized by applications like Microsoft Teams, Slack, and GitHub Desktop) to store logs during the initial installation process [1][4]. Key points regarding these logs and the SquirrelTemp folder: Location: The default path for initial installation logs is %LocalAppData%\SquirrelTemp\SquirrelSetup.log [1][5]. In some instances, depending on the application or if an error occurs, logs may also be found within an application-specific folder, such as %LocalAppData%\YourAppName\SquirrelSetup.log [3]. Purpose: SquirrelTemp serves as a temporary workspace for the Squirrel framework during the installation or updating of an application [4][6]. It is used for staging files before they are moved to their permanent installation directory [6]. Troubleshooting: If an installation fails, the SquirrelSetup.log file within %LocalAppData%\SquirrelTemp is the primary resource for diagnosing the cause [1]. If the log file is missing, it may indicate that the installer was unable to run due to permissions, group policy restrictions, or other environment-level issues [1]. Environment Variables: While %LocalAppData%\SquirrelTemp is the standard location, Squirrel may attempt to use other locations (such as the user's temp directory or %ProgramData%) if it encounters permission issues or if specific system environment variables (like SQUIRREL_TEMP) are set to alternative paths [7]. Users should generally avoid manually modifying or deleting the contents of the SquirrelTemp folder while an application is actively updating, as it may lead to installation errors or incomplete updates [8].

Citations:


Also read the SquirrelTemp installer log

Failure handling only checks %LOCALAPPDATA%\Discord\SquirrelSetup.log; add %LOCALAPPDATA%\SquirrelTemp\SquirrelSetup.log too, since Squirrel writes the initial install log there and the Discord folder may not exist on early failures.

🤖 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/discord/windows.json` at line 20, Extend the
timeout diagnostics after the Discord install-directory check to also inspect
%LOCALAPPDATA%\SquirrelTemp\SquirrelSetup.log. Read and print its tail using the
same existing logging pattern, while preserving the current
Discord\SquirrelSetup.log diagnostics and handling a missing SquirrelTemp
directory or log safely.

Source: MCP tools


🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

sed -n '1,220p' ee/maintained-apps/outputs/discord/windows.json

Repository: fleetdm/fleet

Length of output: 7762


🏁 Script executed:

rg -n "DisplayName -like|DisplayVersion|UninstallEntry|SquirrelSetup|Start-Process -FilePath .* -ArgumentList \"-s\"" ee/maintained-apps/outputs -g '*.json'

Repository: fleetdm/fleet

Length of output: 50370


Don't short-circuit on any Discord* registry hit. A pre-existing Discord, Discord Canary, or Discord PTB entry can make the script exit 0 before the target version is installed. Check for the expected stable app/version, or compare against a pre-install snapshot, before treating the install as complete.

🤖 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/discord/windows.json` at line 20, Update
Get-DiscordUninstallEntry and the polling flow to identify the newly installed
target stable Discord version rather than accepting any existing DisplayName
matching “Discord*”. Capture the pre-install registry state or validate the
expected stable app/version, and only treat a matching new/current entry as
completion; preserve the existing timeout and diagnostics behavior otherwise.

@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

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

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

ee/maintained-apps/outputs/android-studio/windows.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/bdash/darwin.json

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

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

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

ee/maintained-apps/outputs/chrome-remote-desktop-host/darwin.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 // c3c80b80 -> 6890f549 ===

--- /tmp/old.EHMRH5	2026-07-15 17:47:33.433577505 +0000
+++ /tmp/new.xY9LaM	2026-07-15 17:47:33.433577505 +0000
@@ -19,6 +19,7 @@
 
 $uninstallRoots = @(
     "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
+    "HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall",
     "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
     "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
 )
@@ -81,6 +82,15 @@
     Get-ChildItem $installDir -ErrorAction SilentlyContinue |
         Select-Object -ExpandProperty Name |
         ForEach-Object { Write-Host "  $_" }
+    # SquirrelSetup.log records exactly what the installer did, including
+    # whether/where it wrote the uninstall registry entry and why it exited.
+    $squirrelLog = Join-Path $installDir "SquirrelSetup.log"
+    if (Test-Path $squirrelLog) {
+        Write-Host "---- SquirrelSetup.log (tail) ----"
+        Get-Content $squirrelLog -Tail 50 -ErrorAction SilentlyContinue |
+            ForEach-Object { Write-Host $_ }
+        Write-Host "---- end SquirrelSetup.log ----"
+    }
 }
 foreach ($root in $uninstallRoots) {
     Get-ChildItem $root -ErrorAction SilentlyContinue |

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

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

=== Install Script (no changes) ===
=== Uninstall // cb543651 -> b8df2b6f ===

--- /tmp/old.MuCTuf	2026-07-15 17:47:33.776580456 +0000
+++ /tmp/new.zcLOwf	2026-07-15 17:47:33.776580456 +0000
@@ -1,4 +1,4 @@
-$product_code = '{D222FC32-3F3D-5818-9C9E-F00102AE398D}'
+$product_code = '{3DCEFA4A-E4B4-5D5A-BB8F-9F5974FD4C61}'
 $timeoutSeconds = 300  # 5 minute timeout
 
 # Fleet uninstalls app using product code that's extracted on upload

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

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

ee/maintained-apps/outputs/gitup-app/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/kiro-cli/darwin.json

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

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

=== Install // 8dd8cff8 -> bf3091ce ===

--- /tmp/old.cFqE7N	2026-07-15 17:47:33.930581780 +0000
+++ /tmp/new.aUadrt	2026-07-15 17:47:33.930581780 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Excel_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Excel'

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

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

=== Install // 75461837 -> 1ea0c21a ===

--- /tmp/old.fyjB0p	2026-07-15 17:47:33.974582159 +0000
+++ /tmp/new.8F33gy	2026-07-15 17:47:33.974582159 +0000
@@ -96,5 +96,5 @@
 
 # install pkg files
 quit_and_track_application 'com.microsoft.onenote.mac'
-sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.110.26062818_Updater.pkg" -target /
+sudo installer -pkg "$TMPDIR/Microsoft_OneNote_16.111.26071325_Updater.pkg" -target /
 relaunch_application 'com.microsoft.onenote.mac'

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

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

=== Install // fc3e906d -> 3d670a63 ===

--- /tmp/old.T7LSZW	2026-07-15 17:47:34.187583991 +0000
+++ /tmp/new.SUOmkX	2026-07-15 17:47:34.188584000 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_PowerPoint_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Powerpoint'

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

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

=== Install // 3adefd29 -> 9d9d3bd0 ===

--- /tmp/old.5hUJQd	2026-07-15 17:47:34.221584284 +0000
+++ /tmp/new.i5sOmj	2026-07-15 17:47:34.221584284 +0000
@@ -117,6 +117,6 @@
 
 EOF
 
-sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.110.26070318_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
+sudo installer -pkg "$TMPDIR"/Microsoft_Word_16.111.26071325_Installer.pkg -target / -applyChoiceChangesXML "$CHOICE_XML"
 
 relaunch_application 'com.microsoft.Word'

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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