[PR #3085] [CLOSED] fix(hopper): probe user Applications launcher on macOS #5603

Closed
opened 2026-10-31 01:07:54 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/3085
Author: @viniciusdsandrade
Created: 10/14/2026
Status: ❌ Closed

Base: main ← Head: fix/macos-hopper-user-launcher


📝 Commits (6)

  • 2215c72 refactor(hopper): declare macOS Hopper launcher candidates
  • 65797ce fix(config): discover user-installed macOS Hopper launchers
  • 7796458 fix(doctor): probe macOS Hopper launcher candidates
  • ab781b4 docs(installation): document macOS Hopper launcher candidate order
  • 39b5e35 refactor(hopper): reuse shared macOS default launcher constant in config and doctor
  • 10d6bde Merge remote-tracking branch 'origin/main' into HEAD

📊 Changes

7 files changed (+123 additions, -16 deletions)

View changed files

📝 docs/installation.md (+4 -2)
📝 src/application/Doctor.test.ts (+13 -0)
📝 src/application/DoctorDiagnostics.ts (+12 -7)
📝 src/application/MacHopper.test.ts (+10 -0)
📝 src/application/MacHopper.ts (+14 -0)
📝 src/config.test.ts (+53 -0)
📝 src/config/parseConfig.ts (+17 -7)

📄 Description

Summary

Fixes #3054

Probe user-installed Hopper launcher candidates (~/Applications/Hopper Disassembler.app/Contents/MacOS/hopper) when the system-wide installation (/Applications/Hopper Disassembler.app/Contents/MacOS/hopper) is not executable. This aligns macOS runtime Hopper discovery in src/config/parseConfig.ts with doctor diagnostics in src/application/DoctorDiagnostics.ts, allowing CLI analysis to discover Hopper after approved automated setup installs it to ~/Applications.

Problem and expected behavior

On macOS, rea setup installs Hopper into the user's Applications directory (~/Applications/Hopper Disassembler.app/Contents/MacOS/hopper).

When running rea doctor --provider hopper --json, doctor checks manualHopperPaths(), finds the launcher in ~/Applications, and reports healthy ("ok": true, "classification": "healthy").

However, defaultHopperLauncherPath in src/config/parseConfig.ts previously returned DEFAULT_HOPPER_LAUNCHER_PATH (/Applications/Hopper Disassembler.app/Contents/MacOS/hopper) on every non-Linux platform without checking user candidate paths. Consequently, invoking rea analyze ... --provider hopper or rea providers --json without HOPPER_LAUNCHER_PATH set in the ambient environment failed with executable_missing, advising the user to run rea doctor.

Expected behavior: when Hopper is installed in ~/Applications and /Applications does not contain an executable launcher, defaultHopperLauncherPath resolves the user Applications launcher candidate, matching doctor discovery and allowing CLI analysis without requiring manual environment export.

Change and scope

  • In src/application/MacHopper.ts:
    • Export DEFAULT_MAC_HOPPER_LAUNCHER (/Applications/Hopper Disassembler.app/Contents/MacOS/hopper).
    • Export macHopperLauncherCandidates(homeDirectory) returning the system-wide launcher candidate followed by the user Applications launcher candidate.
  • In src/application/MacHopper.test.ts:
    • Add unit test verifying that macHopperLauncherCandidates orders the system candidate before the user Applications candidate.
  • In src/config/parseConfig.ts:
    • Update defaultHopperLauncherPath for platform === "darwin" to probe macHopperLauncherCandidates(homeDirectory) with executable, falling back to DEFAULT_MAC_HOPPER_LAUNCHER.
  • In src/config.test.ts:
    • Add unit tests for darwin verifying that defaultHopperLauncherPath selects the system launcher when present, selects the user Applications launcher when the system copy is missing, prefers system over user when both exist, and falls back to the default path when neither candidate is executable.
  • In src/application/DoctorDiagnostics.ts:
    • Include macHopperLauncherCandidates on host.platform === "darwin" in findHopper, preserving parity between doctor and runtime discovery order.
  • In src/application/Doctor.test.ts:
    • Add test verifying that doctor discovers the user Applications Hopper launcher on macOS.
  • In docs/installation.md:
    • Document that macOS Hopper resolution prefers /Applications/Hopper Disassembler.app/Contents/MacOS/hopper followed by executable ~/Applications/Hopper Disassembler.app/Contents/MacOS/hopper.

Contract and boundary impact

  • Semantic owner and earliest changed stage: configuration parsing in src/config/parseConfig.ts and doctor diagnostics in src/application/DoctorDiagnostics.ts.
  • Contribution scope fit and linked maintainer decision: not applicable (bug fix within existing provider launcher discovery).
  • CLI and MCP/tool-catalog contract: unchanged schemas. Retains existing executable_missing error code and diagnostic structure when no candidate is executable.
  • Provider, bridge, target-format, or platform compatibility: macOS Hopper launcher discovery.
  • Evidence, artifact, provenance, or reconstruction contract: unmodified.
  • Target selection, authority, upstream behavior, and cleanup details (if applicable): no process launch or mutation authority added.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact: none.

Expected effects:

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated:
    • src/application/MacHopper.test.ts: verifies macHopperLauncherCandidates candidate order.
    • src/config.test.ts: verifies defaultHopperLauncherPath resolution on darwin for system, user, priority, and fallback cases.
    • src/application/Doctor.test.ts: verifies doctor discovery of the user Applications Hopper launcher.
  • Base reproduction or other evidence: on the base revision, defaultHopperLauncherPath returned /Applications/Hopper Disassembler.app/Contents/MacOS/hopper unconditionally on macOS even when only ~/Applications/Hopper Disassembler.app/Contents/MacOS/hopper existed.
  • User-visible CLI/MCP output (if applicable): rea providers --json reports hopper availability: available with launcher_path pointing to ~/Applications/.../hopper when only the user installation exists.
  • Remaining proof gaps: tests were verified by source inspection; CI executes the deterministic suite.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • No local test commands were run: verification is source-derived; CI executes the deterministic suite.

Compatibility, safety, and release

  • Breaking changes or migration steps: none.
  • Real Hopper/Ghidra, browser, or OS coverage: none run.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: read-only filesystem existence checks using existing accessSync and executable probes.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/3085 **Author:** [@viniciusdsandrade](https://github.com/viniciusdsandrade) **Created:** 10/14/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/macos-hopper-user-launcher` --- ### 📝 Commits (6) - [`2215c72`](https://github.com/morluto/rea/commit/2215c721c499d05ed4efacf5e199155b8efbb71f) refactor(hopper): declare macOS Hopper launcher candidates - [`65797ce`](https://github.com/morluto/rea/commit/65797ce7990c6af55f9024d99c64ff6572dacba4) fix(config): discover user-installed macOS Hopper launchers - [`7796458`](https://github.com/morluto/rea/commit/7796458600b37d4a045e65365aec5513d7933aae) fix(doctor): probe macOS Hopper launcher candidates - [`ab781b4`](https://github.com/morluto/rea/commit/ab781b422a3b28cbdc1151b0b4ecdcc0049c191b) docs(installation): document macOS Hopper launcher candidate order - [`39b5e35`](https://github.com/morluto/rea/commit/39b5e35193fa9a9f748c9cd577dbd64d481ee81b) refactor(hopper): reuse shared macOS default launcher constant in config and doctor - [`10d6bde`](https://github.com/morluto/rea/commit/10d6bdef5d55c9006a0f44c36bb32cf926cd644c) Merge remote-tracking branch 'origin/main' into HEAD ### 📊 Changes **7 files changed** (+123 additions, -16 deletions) <details> <summary>View changed files</summary> 📝 `docs/installation.md` (+4 -2) 📝 `src/application/Doctor.test.ts` (+13 -0) 📝 `src/application/DoctorDiagnostics.ts` (+12 -7) 📝 `src/application/MacHopper.test.ts` (+10 -0) 📝 `src/application/MacHopper.ts` (+14 -0) 📝 `src/config.test.ts` (+53 -0) 📝 `src/config/parseConfig.ts` (+17 -7) </details> ### 📄 Description ## Summary Fixes #3054 Probe user-installed Hopper launcher candidates (`~/Applications/Hopper Disassembler.app/Contents/MacOS/hopper`) when the system-wide installation (`/Applications/Hopper Disassembler.app/Contents/MacOS/hopper`) is not executable. This aligns macOS runtime Hopper discovery in `src/config/parseConfig.ts` with doctor diagnostics in `src/application/DoctorDiagnostics.ts`, allowing CLI analysis to discover Hopper after approved automated setup installs it to `~/Applications`. ## Problem and expected behavior On macOS, `rea setup` installs Hopper into the user's Applications directory (`~/Applications/Hopper Disassembler.app/Contents/MacOS/hopper`). When running `rea doctor --provider hopper --json`, doctor checks `manualHopperPaths()`, finds the launcher in `~/Applications`, and reports healthy (`"ok": true, "classification": "healthy"`). However, `defaultHopperLauncherPath` in `src/config/parseConfig.ts` previously returned `DEFAULT_HOPPER_LAUNCHER_PATH` (`/Applications/Hopper Disassembler.app/Contents/MacOS/hopper`) on every non-Linux platform without checking user candidate paths. Consequently, invoking `rea analyze ... --provider hopper` or `rea providers --json` without `HOPPER_LAUNCHER_PATH` set in the ambient environment failed with `executable_missing`, advising the user to run `rea doctor`. Expected behavior: when Hopper is installed in `~/Applications` and `/Applications` does not contain an executable launcher, `defaultHopperLauncherPath` resolves the user Applications launcher candidate, matching doctor discovery and allowing CLI analysis without requiring manual environment export. ## Change and scope - In `src/application/MacHopper.ts`: - Export `DEFAULT_MAC_HOPPER_LAUNCHER` (`/Applications/Hopper Disassembler.app/Contents/MacOS/hopper`). - Export `macHopperLauncherCandidates(homeDirectory)` returning the system-wide launcher candidate followed by the user Applications launcher candidate. - In `src/application/MacHopper.test.ts`: - Add unit test verifying that `macHopperLauncherCandidates` orders the system candidate before the user Applications candidate. - In `src/config/parseConfig.ts`: - Update `defaultHopperLauncherPath` for `platform === "darwin"` to probe `macHopperLauncherCandidates(homeDirectory)` with `executable`, falling back to `DEFAULT_MAC_HOPPER_LAUNCHER`. - In `src/config.test.ts`: - Add unit tests for `darwin` verifying that `defaultHopperLauncherPath` selects the system launcher when present, selects the user Applications launcher when the system copy is missing, prefers system over user when both exist, and falls back to the default path when neither candidate is executable. - In `src/application/DoctorDiagnostics.ts`: - Include `macHopperLauncherCandidates` on `host.platform === "darwin"` in `findHopper`, preserving parity between doctor and runtime discovery order. - In `src/application/Doctor.test.ts`: - Add test verifying that doctor discovers the user Applications Hopper launcher on macOS. - In `docs/installation.md`: - Document that macOS Hopper resolution prefers `/Applications/Hopper Disassembler.app/Contents/MacOS/hopper` followed by executable `~/Applications/Hopper Disassembler.app/Contents/MacOS/hopper`. ## Contract and boundary impact - Semantic owner and earliest changed stage: configuration parsing in `src/config/parseConfig.ts` and doctor diagnostics in `src/application/DoctorDiagnostics.ts`. - Contribution scope fit and linked maintainer decision: not applicable (bug fix within existing provider launcher discovery). - CLI and MCP/tool-catalog contract: unchanged schemas. Retains existing `executable_missing` error code and diagnostic structure when no candidate is executable. - Provider, bridge, target-format, or platform compatibility: macOS Hopper launcher discovery. - Evidence, artifact, provenance, or reconstruction contract: unmodified. - Target selection, authority, upstream behavior, and cleanup details (if applicable): no process launch or mutation authority added. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact: none. Expected effects: - [ ] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [x] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: - `src/application/MacHopper.test.ts`: verifies `macHopperLauncherCandidates` candidate order. - `src/config.test.ts`: verifies `defaultHopperLauncherPath` resolution on `darwin` for system, user, priority, and fallback cases. - `src/application/Doctor.test.ts`: verifies doctor discovery of the user Applications Hopper launcher. - Base reproduction or other evidence: on the base revision, `defaultHopperLauncherPath` returned `/Applications/Hopper Disassembler.app/Contents/MacOS/hopper` unconditionally on macOS even when only `~/Applications/Hopper Disassembler.app/Contents/MacOS/hopper` existed. - User-visible CLI/MCP output (if applicable): `rea providers --json` reports `hopper availability: available` with `launcher_path` pointing to `~/Applications/.../hopper` when only the user installation exists. - Remaining proof gaps: tests were verified by source inspection; CI executes the deterministic suite. For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - No local test commands were run: verification is source-derived; CI executes the deterministic suite. ## Compatibility, safety, and release - Breaking changes or migration steps: none. - Real Hopper/Ghidra, browser, or OS coverage: none run. - Package or release metadata impact: none. - Security, privacy, process, or containment review: read-only filesystem existence checks using existing `accessSync` and `executable` probes. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:07:54 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#5603
No description provided.