From 3a683876a66056dede2d45fdc654c4ec28b61d3a Mon Sep 17 00:00:00 2001 From: him0 Date: Wed, 19 Nov 2025 01:05:08 +0900 Subject: [PATCH 1/2] Fix Claude adapter to support shell function definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When `claude` is defined as a shell function (e.g., wrapping ~/.claude/local/claude), the previous implementation failed because shell functions are not inherited by subshells. Changes: - Add `find_claude_executable()` helper to detect executable files only - Check common installation path (~/.claude/local/claude) first - Use `type -P` to find executables, excluding shell functions - Both `ai_can_start()` and `ai_start()` now use the executable path directly This allows the adapter to work correctly even when users have `claude` defined as a shell function that wraps the actual executable. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- adapters/ai/claude.sh | 49 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/adapters/ai/claude.sh b/adapters/ai/claude.sh index ab6b3f0..a03c936 100644 --- a/adapters/ai/claude.sh +++ b/adapters/ai/claude.sh @@ -1,9 +1,44 @@ #!/usr/bin/env bash # Claude Code AI adapter +# Find the actual claude executable (not a shell function) +# Returns the path to the executable, or empty string if not found +find_claude_executable() { + local cmd + + # Check common installation paths first + if [ -x "$HOME/.claude/local/claude" ]; then + echo "$HOME/.claude/local/claude" + return 0 + fi + + # Try to find executable using type -P (Bash/Zsh) + for cmd in claude claude-code; do + if command -v type >/dev/null 2>&1; then + local exe_path + exe_path="$(type -P "$cmd" 2>/dev/null)" && [ -n "$exe_path" ] && { + echo "$exe_path" + return 0 + } + fi + done + + # Fallback: use command -v but exclude functions + for cmd in claude claude-code; do + if type "$cmd" 2>/dev/null | grep -qv "function"; then + if command -v "$cmd" >/dev/null 2>&1; then + echo "$cmd" + return 0 + fi + fi + done + + return 1 +} + # Check if Claude Code is available ai_can_start() { - command -v claude >/dev/null 2>&1 || command -v claude-code >/dev/null 2>&1 + find_claude_executable >/dev/null 2>&1 } # Start Claude Code in a directory @@ -12,7 +47,10 @@ ai_start() { local path="$1" shift - if ! ai_can_start; then + local claude_cmd + claude_cmd="$(find_claude_executable)" + + if [ -z "$claude_cmd" ]; then log_error "Claude Code not found. Install from https://claude.com/claude-code" log_info "The CLI is called 'claude' (or 'claude-code' in older versions)" return 1 @@ -23,10 +61,5 @@ ai_start() { return 1 fi - # Try 'claude' first (official binary name), fallback to 'claude-code' - if command -v claude >/dev/null 2>&1; then - (cd "$path" && claude "$@") - else - (cd "$path" && claude-code "$@") - fi + (cd "$path" && "$claude_cmd" "$@") } From a46631a99fc7eee7d23fac421cd9ccf74986e237 Mon Sep 17 00:00:00 2001 From: him0 Date: Wed, 19 Nov 2025 17:53:59 +0900 Subject: [PATCH 2/2] refactor(claude): improve executable detection logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove unnecessary check for 'type' builtin (always available in Bash) - Replace grep-based function filtering with 'type -t' for accurate detection - Now properly excludes both shell functions and aliases - Only detects actual executable files This addresses PR review feedback about redundant checks and potential false positives when aliases are present. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- adapters/ai/claude.sh | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/adapters/ai/claude.sh b/adapters/ai/claude.sh index a03c936..83feec5 100644 --- a/adapters/ai/claude.sh +++ b/adapters/ai/claude.sh @@ -14,22 +14,18 @@ find_claude_executable() { # Try to find executable using type -P (Bash/Zsh) for cmd in claude claude-code; do - if command -v type >/dev/null 2>&1; then - local exe_path - exe_path="$(type -P "$cmd" 2>/dev/null)" && [ -n "$exe_path" ] && { - echo "$exe_path" - return 0 - } - fi + local exe_path + exe_path="$(type -P "$cmd" 2>/dev/null)" && [ -n "$exe_path" ] && { + echo "$exe_path" + return 0 + } done - # Fallback: use command -v but exclude functions + # Fallback: use type -t to check if it's an executable file for cmd in claude claude-code; do - if type "$cmd" 2>/dev/null | grep -qv "function"; then - if command -v "$cmd" >/dev/null 2>&1; then - echo "$cmd" - return 0 - fi + if [ "$(type -t "$cmd" 2>/dev/null)" = "file" ]; then + command -v "$cmd" + return 0 fi done