Skip to content

fix: locate claude binary when Lumo is launched from Finder - #46

Merged
zhnd merged 1 commit into
mainfrom
fix/locate-claude-binary-from-gui
Apr 13, 2026
Merged

fix: locate claude binary when Lumo is launched from Finder#46
zhnd merged 1 commit into
mainfrom
fix/locate-claude-binary-from-gui

Conversation

@zhnd

@zhnd zhnd commented Apr 13, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the "Claude CLI binary not found in PATH" warning that release builds show when the user launches Lumo from Finder / Launchpad. macOS GUI apps inherit a minimal PATH (/usr/bin:/bin:/usr/sbin:/sbin) and can't see common CLI install prefixes, so which::which("claude") returned None and the CLI probe fell through to the OAuth API path — surfacing a misleading "Claude Code login required" banner.

What changed

  • New services::binary_locator module ported from ClaudeBar's BinaryLocator.swift with a two-tier resolution strategy:
    1. Login shell: spawn $SHELL -l -c 'command -v <name>' so it loads .zshrc / .bashrc / .profile and exposes the full user PATH.
    2. Common paths fallback: walk ~/.local/bin, ~/.cargo/bin, ~/bin, ~/.nix-profile/bin, Homebrew (/opt/homebrew/bin, /usr/local/bin), ~/.npm-global/bin, ~/Library/pnpm, plus nvm / Herd's per-version node/<v>/bin trees sorted by numeric version descending.
  • claude_cli_probe::fetch_usage now calls binary_locator::locate_binary("claude") instead of which::which("claude").

Tests

5 new unit tests in binary_locator::tests:

  • shell_escape_simple / shell_escape_with_quote — POSIX shell escaping
  • human_sort_descends_version_like — numeric-aware sort used for nvm
  • find_in_common_paths_returns_none_for_gibberish — negative case
  • locate_via_login_shell_finds_shend-to-end verification that the login shell resolves a standard POSIX binary

Test plan

  • cargo clippy --workspace -- -D warnings passes
  • cargo test -p app --lib services::binary_locator — 5 tests pass
  • pnpm tauri build → install from DMG → launch from Finder → Usage page should resolve claude via the login shell and render the gauges

🤖 Generated with Claude Code

macOS GUI apps launched from Finder / Launchpad inherit only
`/usr/bin:/bin:/usr/sbin:/sbin` and can't see common install prefixes
like `~/.local/bin`, `/opt/homebrew/bin`, `~/.npm-global/bin`, or
nvm's per-version bin directories. `which::which("claude")` therefore
failed in release builds, which made the CLI probe fall through to the
OAuth API path and surface a misleading "Claude Code login required"
banner to any user whose `claude` binary isn't in the default PATH.

This ports ClaudeBar's `BinaryLocator` (Sources/Infrastructure/Shared/
BinaryLocator.swift) to a new `services::binary_locator` module with
the same two-tier strategy:

1. Run the user's login shell — `$SHELL -l -c 'command -v <name>'`
   — so it loads `.zshrc` / `.bashrc` / `.profile` and sees the same
   PATH the user has in their terminal.
2. Fall back to a hand-rolled list of common install prefixes
   (`~/.local/bin`, `~/.cargo/bin`, Homebrew, Nix, npm-global, pnpm,
   plus nvm / Herd's per-version `node/<v>/bin` walked with numeric
   version sort).

`claude_cli_probe::fetch_usage` now calls `binary_locator::locate_binary`
instead of `which::which("claude")`.

Tests: 5 new unit tests including `locate_via_login_shell_finds_sh`
which verifies end-to-end that the login shell resolves a standard
POSIX binary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@zhnd
zhnd merged commit 57003ab into main Apr 13, 2026
2 checks passed
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.

1 participant