Repository navigation
Fix macOS FMA relaunch for bundle IDs with non-identifier characters - #53570
Conversation
quit_and_track_application and relaunch_application derive the name of the "was it running" flag from the bundle ID and pass it through eval, but only mapped dots and dashes. A bundle ID containing a space split the eval into two assignments, so the flag never landed under the name relaunch reads back and the app was quit during an update but never reopened. Pale Moon (org.mozilla.pale moon) hits this today. Map every character outside [A-Za-z0-9_] via bash parameter expansion, which also drops a subshell and the echo trailing-newline edge case. For bundle IDs drawn from [A-Za-z0-9._-] the derived name is unchanged, so this is inert for 966 of the 967 shipping macOS FMAs. Applied to the generator and to the nine custom install scripts carrying their own copy of the same functions.
There was a problem hiding this comment.
Warning
- Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.
Copilot review overview
🟡 Changes recommended
Regenerate the affected checked-in output manifests so the production Pale Moon script includes the fix.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (1)
What changed in this PR
Fixes macOS FMA relaunch tracking for bundle IDs containing spaces or special characters.
Changes:
- Sanitizes bundle IDs consistently in generated and custom scripts.
- Adds Bash regression and safety tests.
- Adds a user-visible changes record.
- The checked-in Pale Moon output still needs regeneration to include the fix.
| File | Description |
|---|---|
ee/maintained-apps/inputs/homebrew/scripts/webex_install.sh |
Updates relaunch variable derivation. |
ee/maintained-apps/inputs/homebrew/scripts/teleport-suite-install.sh |
Updates relaunch variable derivation. |
ee/maintained-apps/inputs/homebrew/scripts/pd-install.sh |
Updates relaunch variable derivation. |
ee/maintained-apps/inputs/homebrew/scripts/openvpn-connect-install.sh |
Updates relaunch variable derivation. |
ee/maintained-apps/inputs/homebrew/scripts/harmony-sase-install.sh |
Updates relaunch variable derivation. |
ee/maintained-apps/inputs/homebrew/scripts/github-desktop-install.sh |
Updates relaunch variable derivation. |
ee/maintained-apps/inputs/homebrew/scripts/docker_desktop_install.sh |
Updates relaunch variable derivation. |
ee/maintained-apps/inputs/homebrew/scripts/cycling74-max-install.sh |
Updates relaunch variable derivation. |
ee/maintained-apps/inputs/homebrew/scripts/claude-install.sh |
Updates relaunch variable derivation. |
ee/maintained-apps/ingesters/homebrew/scripts.go |
Updates the generated script template. |
ee/maintained-apps/ingesters/homebrew/scripts_test.go |
Adds regression coverage. |
Files excluded by content exclusion policy (1)
- changes/fma-quit-relaunch-bundle-id-with-space
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Removed unnecessary comments from the quitAndTrackApplicationFunc definition.
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
WalkthroughThe change updates generated Homebrew helpers and maintained macOS app installer scripts to derive running-state variable names by replacing characters outside the alphanumeric and underscore set with underscores. Quit and relaunch paths use the same derivation. Tests cover punctuation, spaces, Priority: ⬇️ Low Severity of issue fixed: Low Merge Risk: ⚪ Minimal · up to
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #53570 +/- ##
==========================================
- Coverage 77.37% 76.96% -0.42%
==========================================
Files 4329 4282 -47
Lines 269975 266722 -3253
Branches 15957 14554 -1403
==========================================
- Hits 208903 205284 -3619
- Misses 60882 61259 +377
+ Partials 190 179 -11
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…t-relaunch-varname-eval # Conflicts: # ee/maintained-apps/ingesters/homebrew/scripts_test.go
|
/agentic_review |
Code Review by Qodo
1. Pale Moon still fails to relaunch
|
**Related issue:** Part of #54170 # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [x] Timeouts are implemented and retries are limited to avoid infinite loops ## Testing - [x] Added/updated automated tests - [ ] QA'd all new/changed functionality manually `TestInstallScriptStopsWhenAppWontQuit` runs generated install scripts (app copy and pkg) in bash with `osascript`, `sudo` and friends stubbed. It covers an app that isn't running, one that quits, one that accepts the quit event but keeps running, and one whose quit is canceled. The last two must exit 1 without copying or installing anything. The test fails against `main` and passes with this change. I also ran each edited custom install script end to end with stubs and a refused quit. All of them exit 1 before replacing the app, except Harmony SASE (see below). Docker Desktop's helper was checked under its `set -euo pipefail` for both outcomes. Not run on a real Mac. ## AI **AI:** Claude Code (claude-opus-5-5) ## Summary When a macOS app won't quit (for example, the user cancels a prompt to save changes), the install script moves it aside anyway, copies the new version in, and exits 0. fleetd then deletes `$TMPDIR`, which takes the moved-aside bundle the app is still running from. Fleet reports the update as installed while the user is still on the old version (#54170). Two problems in `quit_and_track_application` caused this: - It confirmed the quit with `pgrep -f "$bundle_id"`, which never matches because a macOS app's command line is its executable path. So it reported success as soon as the quit event was accepted. - When the app was still running at the timeout, it only logged "did not quit", and the caller carried on. Changes: - The helper now polls `osascript … is running` after each quit attempt and returns 1 at the timeout. This matches the KiCad FMA (#54613). An `is running` error doesn't count as quit. - Generated install scripts call `quit_and_track_application '<id>' || exit 1` before replacing the app, for both app-copy and pkg installs. - Custom install scripts that copy the helper get the same fix. Callers stop the install, and Pd detaches its disk image first. Docker Desktop already stopped on failure (it runs under `set -e`) and only needed the `pgrep` fix. **Harmony SASE** keeps going: its pkg force-quits the app on its own, so stopping would block an update that works today. - The `new-fma` skill now says how custom install scripts should quit the app and that helper copies must be kept in sync. Behavior change: a forced patch whose app won't quit now fails, and it's retried on the next policy run instead of being reported as installed. The yaml-files and REST API docs describe when the install is *attempted* ("whether or not the app is open"), which is still accurate, so they're unchanged. Outputs aren't regenerated here: like #43842 and #42951, the FMA bot picks up the new script refs. The 18 frozen macOS apps keep their current scripts until they're unfrozen. Follow-ups (not in this PR): - 12 custom install scripts have their own `quit_application` helper with the same `pgrep` check and no stop on failure: 1Password, Adobe Creative Cloud, Box Tools, ExpressVPN, Google Chrome, Grammarly, Gyazo, Logi Tune, Microsoft Edge, P4V, Slack, Zoom. Each has its own flow, so they need a per-script look. - The uninstall helper `quit_application` has the same `pgrep` check. It's left unchanged here to avoid churning every uninstall script ref. - #53570 changes the `var_name` line of the same helper, in a separate hunk. The Wispr Flow custom script in #54708 copies the old helper and needs this fix after whichever merges second. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * On macOS, updates now stop if the app being replaced doesn’t quit within the timeout. The running app’s files are preserved, and the update is reported as failed rather than installed. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Firefox (release, developer edition, nightly) and KiCad custom install scripts landed on main with the old tr '.-' '__' derivation. Add a test so custom script copies can't reintroduce it.
…se, and Twobird freezes (#56136) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088. Carries every version, URL, hash, and input change from the 2026-10-20 nightly run, so the remaining split PRs are install-script regens only. - macOS nightly version bumps: 1Password 8.12.42, Kiro 1.4.10, MacWhisper 15.7, NetNewsWire 7.2.1, ocenaudio 3.22.1, OpenCode Desktop 2.1.1, Opera 138.0, Plex Media Server 1.43.5.11029, Rectangle 2.0.4, Spokenly 2.32.0, Superhuman Docs 1.0.14, Tableau 2026.3.0. - Windows nightly version bumps: AWS CLI 2.38.2, TablePlus 27.1.2. - MEGAsync 6.7.0 and Mobirise 6.1.17: pinned to the version the installer delivers, and the inputs are now frozen. Both download from version-less URLs (`sha256: no_check`) that now serve newer builds than their casks (6.6.2.0 and 6.1.12), so validation failed on #56088 with "App version ... was not found by osquery". I confirmed both versions by mounting the current DMGs. The unfreeze probe can lift the freezes once the casks catch up. - Twobird: input frozen, version unchanged (1.0.52), output carries the regenerated script. Cloudflare returns 403 to the GitHub macOS runners for `https://www.twobird.com/download/mac-arm64`, so validation failed here and on #55308. The same URL returns 200 from outside CI, including with Go's User-Agent. Freezing makes the validator skip it. Twobird hasn't had a version bump since it was added in June. The macOS outputs here also pick up the regenerated install script from #53570, except 1Password, which uses a custom install script. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed, non-frozen app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
…s-vpn-client) (#56124) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088 (part 1 of 13). Regenerates the install scripts for the 73 macOS Fleet-maintained apps from `010-editor` through `aws-vpn-client` (alphabetical by slug) after #53570 changed how the shared quit and relaunch helpers build their "was running" variable name, so bundle IDs with characters other than dots and dashes relaunch correctly. Every file in this PR gets the same change: a new `install_script_ref` and the regenerated script under `refs`. No versions, installer URLs, or hashes change here; those are in the bumps-and-freezes split. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
…tcat) (#56133) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088 (part 10 of 13). Regenerates the install scripts for the 73 macOS Fleet-maintained apps from `pycharm` through `shortcat` (alphabetical by slug) after #53570 changed how the shared quit and relaunch helpers build their "was running" variable name, so bundle IDs with characters other than dots and dashes relaunch correctly. Every file in this PR gets the same change: a new `install_script_ref` and the regenerated script under `refs`. No versions, installer URLs, or hashes change here; those are in the bumps-and-freezes split. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
…thing-app) (#56134) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088 (part 11 of 13). Regenerates the install scripts for the 73 macOS Fleet-maintained apps from `shotcut` through `syncthing-app` (alphabetical by slug) after #53570 changed how the shared quit and relaunch helpers build their "was running" variable name, so bundle IDs with characters other than dots and dashes relaunch correctly. Every file in this PR gets the same change: a new `install_script_ref` and the regenerated script under `refs`. No versions, installer URLs, or hashes change here; those are in the bumps-and-freezes split. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
…gh devonthink) (#56126) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088 (part 3 of 13). Regenerates the install scripts for the 73 macOS Fleet-maintained apps from `claude-devtools` through `devonthink` (alphabetical by slug) after #53570 changed how the shared quit and relaunch helpers build their "was running" variable name, so bundle IDs with characters other than dots and dashes relaunch correctly. Every file in this PR gets the same change: a new `install_script_ref` and the regenerated script under `refs`. No versions, installer URLs, or hashes change here; those are in the bumps-and-freezes split. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
…through highlight-ai) (#56128) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088 (part 5 of 13). Regenerates the install scripts for the 73 macOS Fleet-maintained apps from `firefly-iota-desktop` through `highlight-ai` (alphabetical by slug) after #53570 changed how the shared quit and relaunch helpers build their "was running" variable name, so bundle IDs with characters other than dots and dashes relaunch correctly. Every file in this PR gets the same change: a new `install_script_ref` and the regenerated script under `refs`. No versions, installer URLs, or hashes change here; those are in the bumps-and-freezes split. Front failed validation on #56088 with a DNS lookup error on the runner. The download resolves and returns 200 now, so a re-run should clear it if it recurs. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
…lpaca) (#56127) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088 (part 4 of 13). Regenerates the install scripts for the 73 macOS Fleet-maintained apps from `devtoys` through `firealpaca` (alphabetical by slug) after #53570 changed how the shared quit and relaunch helpers build their "was running" variable name, so bundle IDs with characters other than dots and dashes relaunch correctly. Every file in this PR gets the same change: a new `install_script_ref` and the regenerated script under `refs`. No versions, installer URLs, or hashes change here; those are in the bumps-and-freezes split. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
…ar) (#56129) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088 (part 6 of 13). Regenerates the install scripts for the 73 macOS Fleet-maintained apps from `hive-app` through `linear` (alphabetical by slug) after #53570 changed how the shared quit and relaunch helpers build their "was running" variable name, so bundle IDs with characters other than dots and dashes relaunch correctly. Every file in this PR gets the same change: a new `install_script_ref` and the regenerated script under `refs`. No versions, installer URLs, or hashes change here; those are in the bumps-and-freezes split. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
…harm-ce) (#56132) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088 (part 9 of 13). Regenerates the install scripts for the 73 macOS Fleet-maintained apps from `opencloud` through `pycharm-ce` (alphabetical by slug) after #53570 changed how the shared quit and relaunch helpers build their "was running" variable name, so bundle IDs with characters other than dots and dashes relaunch correctly. Every file in this PR gets the same change: a new `install_script_ref` and the regenerated script under `refs`. No versions, installer URLs, or hashes change here; those are in the bumps-and-freezes split. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
…ix-workspace) (#56125) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088 (part 2 of 13). Regenerates the install scripts for the 73 macOS Fleet-maintained apps from `axure-rp` through `citrix-workspace` (alphabetical by slug) after #53570 changed how the shared quit and relaunch helpers build their "was running" variable name, so bundle IDs with characters other than dots and dashes relaunch correctly. Every file in this PR gets the same change: a new `install_script_ref` and the regenerated script under `refs`. No versions, installer URLs, or hashes change here; those are in the bumps-and-freezes split. `chatgpt/darwin.json` is rebuilt on top of #55246, so it keeps the dual bundle ID queries already on main and only picks up the new script. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
…installer) (#56130) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088 (part 7 of 13). Regenerates the install scripts for the 73 macOS Fleet-maintained apps from `linearmouse` through `minstaller` (alphabetical by slug) after #53570 changed how the shared quit and relaunch helpers build their "was running" variable name, so bundle IDs with characters other than dots and dashes relaunch correctly. Every file in this PR gets the same change: a new `install_script_ref` and the regenerated script under `refs`. No versions, installer URLs, or hashes change here; those are in the bumps-and-freezes split. MenubarX failed validation on #56088 with a TLS handshake timeout on the runner. The download returns 200 now, so a re-run should clear it if it recurs. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
…wift) (#56135) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088 (part 13 of 13). Regenerates the install scripts for the 61 macOS Fleet-maintained apps from `vnc-viewer` through `zwift` (alphabetical by slug) after #53570 changed how the shared quit and relaunch helpers build their "was running" variable name, so bundle IDs with characters other than dots and dashes relaunch correctly. Every file in this PR gets the same change: a new `install_script_ref` and the regenerated script under `refs`. No versions, installer URLs, or hashes change here; those are in the bumps-and-freezes split. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
…d) (#56131) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088 (part 8 of 13). Regenerates the install scripts for the 73 macOS Fleet-maintained apps from `miro` through `openboard` (alphabetical by slug) after #53570 changed how the shared quit and relaunch helpers build their "was running" variable name, so bundle IDs with characters other than dots and dashes relaunch correctly. Every file in this PR gets the same change: a new `install_script_ref` and the regenerated script under `refs`. No versions, installer URLs, or hashes change here; those are in the bumps-and-freezes split. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
…ough vnc-server) (#56137) **Related issue:** N/A, nightly Fleet-maintained apps ingestion. Split from #56088 (part 12 of 13). Regenerates the install scripts for the 72 macOS Fleet-maintained apps from `syntax-highlight` through `vnc-server` (alphabetical by slug) after #53570 changed how the shared quit and relaunch helpers build their "was running" variable name, so bundle IDs with characters other than dots and dashes relaunch correctly. Every file in this PR gets the same change: a new `install_script_ref` and the regenerated script under `refs`. No versions, installer URLs, or hashes change here; those are in the bumps-and-freezes split. ## Split PRs from #56088 These touch disjoint files and can merge in any order. - #56136 Nightly version bumps; MEGAsync, Mobirise, and Twobird freezes - #56124 Script regen 1/13: 010-editor through aws-vpn-client - #56125 Script regen 2/13: axure-rp through citrix-workspace - #56126 Script regen 3/13: claude-devtools through devonthink - #56127 Script regen 4/13: devtoys through firealpaca - #56128 Script regen 5/13: firefly-iota-desktop through highlight-ai - #56129 Script regen 6/13: hive-app through linear - #56130 Script regen 7/13: linearmouse through minstaller - #56131 Script regen 8/13: miro through openboard - #56132 Script regen 9/13: opencloud through pycharm-ce - #56133 Script regen 10/13: pycharm through shortcat - #56134 Script regen 11/13: shotcut through syncthing-app - #56137 Script regen 12/13: syntax-highlight through vnc-server - #56135 Script regen 13/13: vnc-viewer through zwift # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [ ] QA'd all new/changed functionality manually The darwin FMA validator runs against every changed app in this PR. ## AI **AI:** Claude Code (claude-opus-5-5)
Install: apply #53570's var_name derivation to quit_and_track_application and relaunch_application, so the copies match scripts.go byte-for-byte. For com.github.wez.wezterm the derived name is unchanged. Uninstall: rebuild wezterm-uninstall.sh from the current generator (#56457) with only the rm -rf path changed to /Applications/WezTerm.app. It picks up the login-window-safe trash() that TestCustomUninstallScriptsUseCurrentTrash requires, and quit_application 'com.github.wez.wezterm' || exit 1 before the bundle is removed. trash() now skips ~ paths with no GUI user, so the LOGGED_IN_USER guard around the calls is no longer needed. WezTerm is frozen, so swap the embedded scripts and refs in darwin.json by hand: install 056ac45d -> 57c7d5cf, uninstall fce4539f -> 4db160b2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Related issue: NA — found while reviewing #53566
Checklist for submitter
changes/.SELECT *is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters.What & why
quit_and_track_applicationandrelaunch_applicationderive the name of the "was it running" flag from the bundle ID and interpolate it into aneval:tr '.-' '__'maps only dots and dashes. Any other character survives into the variable name, and a space breaks theevalin two:eval "export APP_WAS_RUNNING_org_mozilla_pale moon=1"—exporttakes two arguments, so it setsAPP_WAS_RUNNING_org_mozilla_paleand a straymoon=1. The intended variable is never set.eval "was_running=$APP_WAS_RUNNING_org_mozilla_pale moon"— assigns empty, then tries to runmoonas a command, printingmoon: command not foundinto the install output.was_runningis empty, sorelaunch_applicationreturns early.Pale Moon hits this today.
pale-moon.jsonhas"unique_identifier": "org.mozilla.pale moon", and the shipped script callsquit_and_track_application 'org.mozilla.pale moon'. The app is quit during an update and never reopened. It is the only one of the 967 shipping macOS FMAs affected — every other identifier is drawn from[A-Za-z0-9._-].This replaces the derivation with bash parameter expansion that maps everything outside
[A-Za-z0-9_]:Also applied to the thirteen custom install scripts under
inputs/homebrew/scripts/that carry their own copy of these functions, so the two don't drift.Reviewer notes
[A-Za-z0-9._-]the new mapping produces a byte-identical variable name totr '.-' '__'. I compared old vs. new across all 967 homebrewunique_identifiervalues: 966 identical, 1 changed (pale-moon, the broken one). Runtime behavior for every other app is unchanged.tr -c '[:alnum:]_' '_'. Same result, but no subshell, and it sidesteps two hazards:echoappends a newline thattr -cwould map to a trailing underscore, and BSD vs. GNUtrdifferences in CI. Verified on/bin/bash3.2, the macOS runtime — generated scripts have used a bash shebang since Use bash shebang in generated scripts #44836.unique_identifiercomes from Fleet's own input files, not the brew API, so this isn't the untrusted-input class Escape cask metadata in Homebrew Fleet-maintained-app script generation #51324 addressed. Hardening theevalis still worthwhile because the name reaches a root-privilegedeval, but the bug being fixed is the relaunch failure.Testing
Added/updated automated tests
TestQuitRelaunchVarNameSurvivesEvalruns the real write/read round trip through bash for four shipping identifier shapes includingorg.mozilla.pale moon, and asserts the flag survives.TestQuitRelaunchVarNameNeutralizesCommandSubstitutionasserts the derived name is a bare shell identifier and that a$(touch ...)payload doesn't execute.TestQuitAndRelaunchDeriveVarNameIdenticallypins the two derivations to the same line so they can't drift, andTestCustomInstallScriptsDoNotUseOldVarNameDerivationfails if any custom install script still usestr '.-' '__'.Confirmed these fail against the old derivation: under
set -u, pale-moon errors withAPP_WAS_RUNNING_org_mozilla_pale: unbound variable; without it, the read back is silently empty.QA'd all new/changed functionality manually
go test ./ee/maintained-apps/...passes.bash -nclean on all thirteen patched custom scripts.go vetandgofmtclean. (make lint-go-incrementalcouldn't run locally — it needs a network clone of golangci-lint — so leaving that to CI.)AI
AI: Claude Code (claude-opus-5)
Summary by CodeRabbit
Bug Fixes
Tests