Initial upload: Local LLM Prompt Manager CLI tool
This commit is contained in:
99
src/commands/commit.py
Normal file
99
src/commands/commit.py
Normal file
@@ -0,0 +1,99 @@
|
||||
"""Git commit message generation command."""
|
||||
|
||||
from typing import Optional
|
||||
|
||||
import click
|
||||
|
||||
from ..git import GitUtils
|
||||
from ..llm import LLMClientFactory
|
||||
|
||||
COMMIT_MESSAGE_PROMPT = """You are a helpful assistant that generates git commit messages.
|
||||
|
||||
Analyze the following git diff and generate a concise, descriptive commit message.
|
||||
|
||||
Diff:
|
||||
{diff}
|
||||
|
||||
Files changed:
|
||||
{files}
|
||||
|
||||
Generate a commit message in the following format:
|
||||
- Maximum 72 characters for the title
|
||||
- Blank line
|
||||
- Detailed description of changes
|
||||
|
||||
Focus on:
|
||||
1. What changed
|
||||
2. Why it changed
|
||||
3. Any breaking changes
|
||||
|
||||
Commit message:"""
|
||||
|
||||
|
||||
@click.command("commit")
|
||||
@click.option("--provider", default=None, help="LLM provider")
|
||||
@click.option("--model", default=None, help="Model name")
|
||||
@click.option("--stream/--no-stream", default=False, help="Stream the response")
|
||||
@click.option("--copy/--no-copy", default=True, help="Copy to clipboard")
|
||||
def generate_commit(
|
||||
provider: Optional[str],
|
||||
model: Optional[str],
|
||||
stream: bool,
|
||||
copy: bool
|
||||
):
|
||||
"""Generate a git commit message from staged changes."""
|
||||
from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
from rich.text import Text
|
||||
|
||||
if not GitUtils.is_git_repo():
|
||||
click.echo("Error: Not in a git repository", err=True)
|
||||
click.echo("Run this command from a directory with a .git folder", err=True)
|
||||
return
|
||||
|
||||
staged_diff = GitUtils.get_staged_diff()
|
||||
staged_files = GitUtils.get_staged_files()
|
||||
|
||||
if not staged_diff:
|
||||
click.echo("No staged changes found", err=True)
|
||||
click.echo("Stage your changes with 'git add' first", err=True)
|
||||
return
|
||||
|
||||
if not staged_files:
|
||||
click.echo("No files staged", err=True)
|
||||
return
|
||||
|
||||
console = Console()
|
||||
|
||||
click.echo("Generating commit message...")
|
||||
|
||||
prompt = COMMIT_MESSAGE_PROMPT.format(
|
||||
diff=GitUtils.get_diff_summary(staged_diff),
|
||||
files="\n".join(staged_files[:20])
|
||||
)
|
||||
|
||||
client = LLMClientFactory.create(provider=provider)
|
||||
|
||||
if stream:
|
||||
click.echo("\n--- Generated Commit Message ---")
|
||||
response = ""
|
||||
for chunk in client.stream_generate(prompt, model=model):
|
||||
response += chunk
|
||||
console.print(chunk, end="")
|
||||
click.echo()
|
||||
else:
|
||||
response = client.generate(prompt, model=model)
|
||||
|
||||
click.echo("\n--- Generated Commit Message ---")
|
||||
console.print(Panel(Text(response), title="Commit Message"))
|
||||
|
||||
if copy:
|
||||
try:
|
||||
import pyperclip
|
||||
pyperclip.copy(response.strip())
|
||||
click.echo("Copied to clipboard!")
|
||||
except ImportError:
|
||||
click.echo("(Install pyperclip to enable clipboard copy)")
|
||||
|
||||
if click.confirm("\nUse this commit message?"):
|
||||
click.echo(f"\nRun: git commit -m '{response.strip()}'")
|
||||
Reference in New Issue
Block a user