Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions src/codegen/cli/commands/claude/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,22 +184,15 @@ def _run_claude_interactive(resolved_org_id: int, no_mcp: bool | None) -> None:
# Initialize log watcher manager
log_watcher_manager = ClaudeLogWatcherManager()

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

Expand Down Expand Up @@ -373,6 +366,24 @@ def claude(
},
)

# Check if Claude is installed for interactive mode (not needed for background mode)
if background is None:
claude_path = resolve_claude_path()
if not claude_path:
logger.error(
"Claude CLI not found",
extra={"operation": "claude.command", "error_type": "claude_cli_not_found", **_get_session_context()},
)
# Use t_console (the visible console) for error messages instead of the quiet console
t_console.print("\n[red bold]❌ Claude Code Not Installed[/red bold]")
t_console.print("\n[yellow]Claude Code CLI is not installed or cannot be found.[/yellow]")
t_console.print("\n[bold]To install Claude Code:[/bold]")
t_console.print(" • Install globally: [cyan]npm install -g @anthropic-ai/claude-code[/cyan]")
t_console.print(" • Or run: [cyan]claude /migrate-installer[/cyan] for local installation")
t_console.print("\n[dim]If you migrated a local install, ensure ~/.claude/local/claude exists[/dim]")
t_console.print("[dim]or add it to your PATH.[/dim]")
raise typer.Exit(1)

# Resolve org_id early for session management
resolved_org_id = resolve_org_id(org_id)
if resolved_org_id is None:
Expand Down
32 changes: 29 additions & 3 deletions src/codegen/cli/tui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -570,9 +570,26 @@ def _display_dashboard_tab(self):

def _display_claude_tab(self):
"""Display the Claude Code interface tab."""
print(" \033[37m→ Run Claude Code\033[0m")
print()
print("Press Enter to launch Claude Code with session tracking.")
# Check if Claude Code is installed
from codegen.cli.commands.claude.utils import resolve_claude_path

claude_path = resolve_claude_path()
if not claude_path:
# Display error message when Claude is not installed
print(" \033[31m✗ Claude Code Not Installed\033[0m")
print()
print("\033[33m⚠ Claude Code CLI is not installed or cannot be found.\033[0m")
print()
print("To install Claude Code:")
print(" • Install globally: \033[36mnpm install -g @anthropic-ai/claude-code\033[0m")
print(" • Or run: \033[36mclaude /migrate-installer\033[0m for local installation")
print()
print("Once installed, restart this CLI to use Claude Code.")
else:
print(" \033[37m→ Run Claude Code\033[0m")
print()
print("Press Enter to launch Claude Code with session tracking.")

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Claude Tab Layout Inconsistent Across Installations

The _display_claude_tab function calls _pad_to_lines(7) with a hardcoded value. This doesn't account for the varying number of lines printed before padding (3 lines when Claude Code is installed, 9 lines when not). As a result, the Claude tab's content area doesn't consistently maintain its intended 10-line fixed layout, displaying 12 lines when Claude is not installed and 6 lines when it is.

Fix in Cursor Fix in Web

# The claude tab main content area should be a fixed 10 lines
self._pad_to_lines(7)

Expand Down Expand Up @@ -892,6 +909,15 @@ def _handle_dashboard_tab_keypress(self, key: str):
def _handle_claude_tab_keypress(self, key: str):
"""Handle keypresses in the claude tab."""
if key == "\r" or key == "\n": # Enter - run Claude Code
# Check if Claude is installed before attempting to run
from codegen.cli.commands.claude.utils import resolve_claude_path

claude_path = resolve_claude_path()
if not claude_path:
# Claude is not installed, don't try to launch
logger.warning("Attempted to launch Claude Code but it's not installed", extra={"operation": "tui.launch_claude", "error": "not_installed"})
return

self._run_claude_code()

def _run_claude_code(self):
Expand Down
Loading