feat(claude-binary): implement robust version selector with enhanced binary detection

This commit provides a comprehensive solution to Claude binary detection issues
by implementing a user-friendly version selector UI and improving the binary
discovery logic. It addresses all concerns raised in multiple PRs and comments.

Changes:
- Add ClaudeVersionSelector component for selecting from multiple installations
- Update ClaudeBinaryDialog to use version selector instead of manual path input
- Fix unused variable warning in production builds (claude.rs:442)
- Improve select_best_installation to handle production build restrictions
- Add listClaudeInstallations API endpoint to fetch all available installations
- Make Claude version indicator clickable to navigate to Settings
- Move Claude installation selector to General tab in Settings (per user request)
- Enhance dialog UX with loading states and clear installation instructions
- Add Radix UI radio-group dependency for version selector

Fixes:
- Production build warning about unused claude_path variable
- Version detection failures in production builds due to process restrictions
- Poor UX when Claude binary is not found (now shows helpful dialog)
- Inability to easily switch between multiple Claude installations

This implementation takes inspiration from:
- PR #3: Version selector dropdown approach (preferred by users)
- PR #4: Binary detection improvements and path validation
- PR #39: Additional detection methods and error handling
- Commit 5a29f9a: Shared claude binary detection module architecture

Addresses feedback from:
- getAsterisk/claudia#4 (comment): User preference for dropdown selector
- Production build restrictions that prevent version detection
- Need for better error handling when Claude is not installed

The solution provides a seamless experience whether Claude is installed via:
- npm/yarn/bun global installation
- nvm-managed Node.js versions
- Homebrew on macOS
- System-wide installation
- Local user installation (~/.local/bin, etc.)

Refs: #3, #4, #39, 5a29f9a
This commit is contained in:
Mufeed VH
2025-06-25 02:49:24 +05:30
parent 97290e5665
commit c48a63f170
14 changed files with 556 additions and 77 deletions

View File

@@ -95,21 +95,28 @@ export const Topbar: React.FC<TopbarProps> = ({
if (!versionStatus) return null;
const statusContent = (
<div className="flex items-center space-x-2 text-xs">
<Circle
className={cn(
"h-3 w-3",
versionStatus.is_installed
? "fill-green-500 text-green-500"
: "fill-red-500 text-red-500"
)}
/>
<span>
{versionStatus.is_installed && versionStatus.version
? `Claude Code ${versionStatus.version}`
: "Claude Code"}
</span>
</div>
<Button
variant="ghost"
size="sm"
className="h-auto py-1 px-2 hover:bg-accent"
onClick={onSettingsClick}
>
<div className="flex items-center space-x-2 text-xs">
<Circle
className={cn(
"h-3 w-3",
versionStatus.is_installed
? "fill-green-500 text-green-500"
: "fill-red-500 text-red-500"
)}
/>
<span>
{versionStatus.is_installed && versionStatus.version
? `Claude Code ${versionStatus.version}`
: "Claude Code"}
</span>
</div>
</Button>
);
if (!versionStatus.is_installed) {
@@ -124,6 +131,14 @@ export const Topbar: React.FC<TopbarProps> = ({
{versionStatus.output}
</pre>
</div>
<Button
variant="outline"
size="sm"
className="w-full"
onClick={onSettingsClick}
>
Select Claude Installation
</Button>
<a
href="https://www.anthropic.com/claude-code"
target="_blank"