2026-02-28 18:03:12 +00:00
|
|
|
package cmd
|
2026-02-28 18:28:27 +00:00
|
|
|
|
2026-02-28 19:56:23 +00:00
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
|
|
|
|
|
"github.com/fatih/color"
|
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
|
"github.com/spf13/viper"
|
|
|
|
|
"gmgauthier.com/grokkit/internal/git"
|
|
|
|
|
"gmgauthier.com/grokkit/internal/grok"
|
|
|
|
|
)
|
2026-02-28 18:28:27 +00:00
|
|
|
|
|
|
|
|
var commitMsgCmd = &cobra.Command{
|
|
|
|
|
Use: "commit-msg",
|
|
|
|
|
Short: "Generate conventional commit message from staged changes",
|
|
|
|
|
Run: func(cmd *cobra.Command, args []string) {
|
2026-02-28 19:56:23 +00:00
|
|
|
model := viper.GetString("model")
|
|
|
|
|
|
|
|
|
|
client := grok.NewClient()
|
|
|
|
|
|
|
|
|
|
if !git.IsRepo() {
|
|
|
|
|
color.Red("Error: Not inside a git repository")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
diffOutput := git.Run([]string{"diff", "--cached"})
|
|
|
|
|
|
|
|
|
|
if diffOutput == "" {
|
|
|
|
|
color.Red("Error: No staged changes. Stage files with `git add` first.")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
systemPrompt := `You are an expert at writing conventional commit messages.
|
|
|
|
|
|
|
|
|
|
Analyze the code diff below and generate a concise commit message:
|
|
|
|
|
|
|
|
|
|
- Prefix: feat|fix|docs|style|refactor|perf|test|ci|chore
|
|
|
|
|
- Imperative mood (e.g., 'Add', 'Fix'), capitalize first letter
|
|
|
|
|
- Max 72 chars for subject line
|
|
|
|
|
- Optional body lines wrapped at 72 chars
|
|
|
|
|
- No trailing period on subject`
|
|
|
|
|
|
|
|
|
|
messages := []map[string]string{
|
|
|
|
|
{"role": "system", "content": systemPrompt},
|
|
|
|
|
{"role": "user", "content": diffOutput},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
commitMsg := client.Stream(messages, model)
|
|
|
|
|
|
|
|
|
|
fmt.Println(color.YellowString("Suggested commit message:"))
|
|
|
|
|
fmt.Println()
|
|
|
|
|
fmt.Print(color.CyanString(commitMsg))
|
|
|
|
|
fmt.Println()
|
2026-02-28 18:28:27 +00:00
|
|
|
},
|
|
|
|
|
}
|