Files
git-commit-message-generator/app/src/git_commit_generator/interactive.py
2026-02-04 19:06:15 +00:00

137 lines
4.3 KiB
Python

"""Interactive mode for message refinement."""
from enum import Enum
from typing import Optional
from rich.console import Console
from rich.prompt import Prompt
from rich.text import Text
class Action(Enum):
"""User action options in interactive mode."""
ACCEPT = "a"
EDIT = "e"
REGENERATE = "r"
QUIT = "q"
class InteractiveMode:
"""Interactive mode handler for message refinement."""
def __init__(self):
"""Initialize interactive mode."""
self.console = Console()
def show_message(self, message: str) -> None:
"""Display a message to the user."""
self.console.print(Text(message, style="bold green"))
def show_diff(self, diff: str) -> None:
"""Display the diff being analyzed."""
self.console.print("\n[bold]Changes detected:[/bold]")
self.console.print(diff[:500] + "..." if len(diff) > 500 else diff)
def prompt_for_action(self, current_message: str) -> tuple[Action, Optional[str]]:
"""Prompt user for action."""
self.console.print("\n[bold]Generated commit message:[/bold]")
self.console.print(f"[cyan]{current_message}[/cyan]")
self.console.print("\n[bold]Options:[/bold]")
self.console.print(" [green](a)[/green]ccept message")
self.console.print(" [green](e)[/green]dit message")
self.console.print(" [green](r)[/green]egenerate")
self.console.print(" [green](q)[/green]uit")
choice = Prompt.ask(
"What would you like to do?",
choices=["a", "e", "r", "q"],
default="a",
).lower()
if choice == "a":
return Action.ACCEPT, None
elif choice == "e":
edited = Prompt.ask("Enter new commit message", default=current_message)
return Action.ACCEPT, edited
elif choice == "r":
return Action.REGENERATE, None
else:
return Action.QUIT, None
def confirm_commit(self, message: str) -> bool:
"""Confirm the commit message before proceeding."""
self.console.print("\n[bold]Final commit message:[/bold]")
self.console.print(f"[green]{message}[/green]")
confirm = Prompt.ask(
"Proceed with commit?",
choices=["y", "n"],
default="y",
).lower()
return confirm == "y"
def show_error(self, error: str) -> None:
"""Display an error message."""
self.console.print(Text(f"Error: {error}", style="bold red"))
def show_info(self, info: str) -> None:
"""Display an info message."""
self.console.print(Text(info, style="blue"))
def show_connection_status(
self, connected: bool, model: Optional[str] = None
) -> None:
"""Show Ollama connection status."""
if connected:
status = "[green]Connected to Ollama[/green]"
if model:
status += f" (model: {model})"
self.console.print(status)
else:
self.console.print(
Text(
"Could not connect to Ollama. Make sure it's running.",
style="bold red",
)
)
def show_no_changes_warning(self) -> None:
"""Show warning when no changes detected."""
self.console.print(
Text(
"No changes detected. Stage some files with 'git add' or use --unstaged flag.",
style="bold yellow",
)
)
def show_help(self) -> None:
"""Show help information."""
help_text = """
[bold]Git Commit Message Generator[/bold]
A CLI tool that generates conventional git commit messages using local LLMs.
[bold]Commands:[/bold]
generate Generate a commit message from staged/unstaged changes
changelog Generate CHANGELOG.md from git history
config Configure settings
[bold]Options:[/bold]
--unstaged Include unstaged changes
--staged Include only staged changes (default)
--model Specify which model to use
--interactive, -i Use interactive mode
[bold]Environment Variables:[/bold]
OLLAMA_HOST Ollama server URL (default: http://localhost:11434)
OLLAMA_MODEL Default model to use
"""
self.console.print(help_text)
def get_interactive_mode() -> InteractiveMode:
"""Get InteractiveMode instance."""
return InteractiveMode()