Skip to content

Commit e9f8e63

Browse files
authored
fix: check for claude install first (#1261)
# Motivation <!-- Why is this change necessary? --> # Content <!-- Please include a summary of the change --> # Testing <!-- How was the change tested? --> # Please check the following before marking your PR as ready for review - [ ] I have added tests for my changes - [ ] I have updated the documentation or added new documentation as needed
1 parent 1c82d0a commit e9f8e63

File tree

2 files changed

+50
-13
lines changed

2 files changed

+50
-13
lines changed

src/codegen/cli/commands/claude/main.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -184,22 +184,15 @@ def _run_claude_interactive(resolved_org_id: int, no_mcp: bool | None) -> None:
184184
# Initialize log watcher manager
185185
log_watcher_manager = ClaudeLogWatcherManager()
186186

187-
# Resolve Claude CLI path and test accessibility
187+
# Resolve Claude CLI path (we already checked it exists in the main claude() function)
188188
claude_path = resolve_claude_path()
189189
if not claude_path:
190+
# This should not happen since we check earlier, but handle it just in case
190191
logger.error(
191-
"Claude CLI not found",
192+
"Claude CLI not found in interactive mode",
192193
extra={"operation": "claude.interactive", "org_id": resolved_org_id, "claude_session_id": session_id, "error_type": "claude_cli_not_found", **_get_session_context()},
193194
)
194195
console.print("❌ Claude Code CLI not found.", style="red")
195-
console.print(
196-
"💡 If you migrated a local install, ensure `~/.claude/local/claude` exists, or add it to PATH.",
197-
style="dim",
198-
)
199-
console.print(
200-
"💡 Otherwise install globally via npm (e.g., `npm i -g claude`) or run `claude /migrate`.",
201-
style="dim",
202-
)
203196
update_claude_session_status(session_id, "ERROR", resolved_org_id)
204197
raise typer.Exit(1)
205198

@@ -373,6 +366,24 @@ def claude(
373366
},
374367
)
375368

369+
# Check if Claude is installed for interactive mode (not needed for background mode)
370+
if background is None:
371+
claude_path = resolve_claude_path()
372+
if not claude_path:
373+
logger.error(
374+
"Claude CLI not found",
375+
extra={"operation": "claude.command", "error_type": "claude_cli_not_found", **_get_session_context()},
376+
)
377+
# Use t_console (the visible console) for error messages instead of the quiet console
378+
t_console.print("\n[red bold]❌ Claude Code Not Installed[/red bold]")
379+
t_console.print("\n[yellow]Claude Code CLI is not installed or cannot be found.[/yellow]")
380+
t_console.print("\n[bold]To install Claude Code:[/bold]")
381+
t_console.print(" • Install globally: [cyan]npm install -g @anthropic-ai/claude-code[/cyan]")
382+
t_console.print(" • Or run: [cyan]claude /migrate-installer[/cyan] for local installation")
383+
t_console.print("\n[dim]If you migrated a local install, ensure ~/.claude/local/claude exists[/dim]")
384+
t_console.print("[dim]or add it to your PATH.[/dim]")
385+
raise typer.Exit(1)
386+
376387
# Resolve org_id early for session management
377388
resolved_org_id = resolve_org_id(org_id)
378389
if resolved_org_id is None:

src/codegen/cli/tui/app.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -570,9 +570,26 @@ def _display_dashboard_tab(self):
570570

571571
def _display_claude_tab(self):
572572
"""Display the Claude Code interface tab."""
573-
print(" \033[37m→ Run Claude Code\033[0m")
574-
print()
575-
print("Press Enter to launch Claude Code with session tracking.")
573+
# Check if Claude Code is installed
574+
from codegen.cli.commands.claude.utils import resolve_claude_path
575+
576+
claude_path = resolve_claude_path()
577+
if not claude_path:
578+
# Display error message when Claude is not installed
579+
print(" \033[31m✗ Claude Code Not Installed\033[0m")
580+
print()
581+
print("\033[33m⚠ Claude Code CLI is not installed or cannot be found.\033[0m")
582+
print()
583+
print("To install Claude Code:")
584+
print(" • Install globally: \033[36mnpm install -g @anthropic-ai/claude-code\033[0m")
585+
print(" • Or run: \033[36mclaude /migrate-installer\033[0m for local installation")
586+
print()
587+
print("Once installed, restart this CLI to use Claude Code.")
588+
else:
589+
print(" \033[37m→ Run Claude Code\033[0m")
590+
print()
591+
print("Press Enter to launch Claude Code with session tracking.")
592+
576593
# The claude tab main content area should be a fixed 10 lines
577594
self._pad_to_lines(7)
578595

@@ -892,6 +909,15 @@ def _handle_dashboard_tab_keypress(self, key: str):
892909
def _handle_claude_tab_keypress(self, key: str):
893910
"""Handle keypresses in the claude tab."""
894911
if key == "\r" or key == "\n": # Enter - run Claude Code
912+
# Check if Claude is installed before attempting to run
913+
from codegen.cli.commands.claude.utils import resolve_claude_path
914+
915+
claude_path = resolve_claude_path()
916+
if not claude_path:
917+
# Claude is not installed, don't try to launch
918+
logger.warning("Attempted to launch Claude Code but it's not installed", extra={"operation": "tui.launch_claude", "error": "not_installed"})
919+
return
920+
895921
self._run_claude_code()
896922

897923
def _run_claude_code(self):

0 commit comments

Comments
 (0)