Skip to content

Commit b934ff4

Browse files
committed
feat(cli): package assets with go:embed
and wire interactive AI choice
1 parent 17051b5 commit b934ff4

8 files changed

Lines changed: 94 additions & 32 deletions

File tree

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,15 +148,18 @@ Actions:
148148
n - Reject and exit
149149
e - Edit message manually
150150
r - Regenerate different suggestion
151+
a - Upgrade suggestion with Local AI (Ollama)
151152
152-
Choice [y/n/e/r]:
153+
Choice [y/n/e/r/a]:
153154
```
154155
155156
**Interactive Options:**
156157
- **`y`** (or press Enter) - Accept the suggestion and commit
157158
- **`n`** - Reject and exit without committing
158159
- **`e`** - Edit the message manually with your own text
159160
- **`r`** - Regenerate a completely different suggestion using intelligent variation algorithms
161+
- **`a`** - **Upgrade to Local AI**: If you are using the heuristic engine, this attempts to connect to Ollama for a more semantic suggestion
162+
- **`h`** - **Fallback to Heuristic**: If you are in AI mode, this switches back to the classic rule-based engine
160163
161164
### Command-Line Options
162165

assets/assets.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package assets
2+
3+
import (
4+
"bytes"
5+
"embed"
6+
"text/template"
7+
)
8+
9+
//go:embed prompts/* messages/*
10+
var Files embed.FS
11+
12+
// GetPrompt returns the system prompt template
13+
func GetPrompt() (string, error) {
14+
b, err := Files.ReadFile("prompts/system_prompt.txt")
15+
return string(b), err
16+
}
17+
18+
// GetOllamaWarning returns the Ollama warning message
19+
func GetOllamaWarning() (string, error) {
20+
b, err := Files.ReadFile("messages/ollama_warning.txt")
21+
return string(b), err
22+
}
23+
24+
// GetInitSuccess returns the initialization success message
25+
func GetInitSuccess() (string, error) {
26+
b, err := Files.ReadFile("messages/init_success.txt")
27+
return string(b), err
28+
}
29+
30+
// RenderOllamaWarning renders the Ollama warning message with the provided context
31+
func RenderOllamaWarning(url, model string) (string, error) {
32+
warningTmpl, err := GetOllamaWarning()
33+
if err != nil {
34+
return "", err
35+
}
36+
tmpl, err := template.New("warning").Parse(warningTmpl)
37+
if err != nil {
38+
return "", err
39+
}
40+
var buf bytes.Buffer
41+
if err := tmpl.Execute(&buf, struct{ URL, Model string }{URL: url, Model: model}); err != nil {
42+
return "", err
43+
}
44+
return buf.String(), nil
45+
}

assets/messages/init_success.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
You can now customize the configuration to fit your project's needs.
3+
4+
Configuration hierarchy:
5+
1. Local (.gitmit.json) - project-specific settings
6+
2. Global (~/.gitmit.json) - user-wide settings
7+
3. Default (embedded) - built-in defaults

assets/messages/ollama_warning.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
⚠️ Ollama connection not detected on {{.URL}}
2+
To enable Local AI generation, please ensure:
3+
1. Ollama is running locally (`ollama serve`)
4+
2. The required model is pulled (`ollama pull {{.Model}}`)
5+
3. Your .gitmit.json sets "engine": "ollama"
6+
7+
Falling back to interactive options...

assets/prompts/system_prompt.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
You are an expert developer assistant. Analyze the provided structured git diff metadata and generate a single-line commit message following the Conventional Commits specification.
2+
3+
Guidelines:
4+
1. Format MUST be: <type>(<scope>): <short description in present tense>
5+
2. Allowed types: feat, fix, refactor, chore, test, docs, style, perf, ci, build, security
6+
3. Do NOT include any markdown, backticks, quotes, or introductory text like "Here is your commit message:".
7+
4. Output ONLY the raw string of the commit message.
8+
9+
Metadata Context:
10+
- Project Type: {{.ProjectType}}
11+
- Active Branch Name: {{.CurrentBranch}}
12+
- Detected Intent/Type Bonus: {{.RecommendedType}}
13+
- Modified Files: {{range .Files}}{{.}}, {{end}}
14+
- Key Code Symbols Altered: {{range .CodeSymbols}}{{.}}, {{end}}
15+
- Dependency Changes: {{.DependencyAlert}}
16+
- Added/Deleted Line Ratio: {{printf "%.2f" .DiffSummary.Ratio}}
17+
18+
Output:

cmd/init.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/fatih/color"
99
"github.com/spf13/cobra"
1010

11+
"gitmit/assets"
1112
"gitmit/internal/config"
1213
)
1314

@@ -152,11 +153,9 @@ func runInit(cmd *cobra.Command, args []string) error {
152153

153154
color.Green("✅ Created config file: %s", configPath)
154155
color.Blue("\n📝 Detected project type: %s", projectType)
155-
fmt.Println("\nYou can now customize the configuration to fit your project's needs.")
156-
fmt.Println("\nConfiguration hierarchy:")
157-
fmt.Println(" 1. Local (.gitmit.json) - project-specific settings")
158-
fmt.Println(" 2. Global (~/.gitmit.json) - user-wide settings")
159-
fmt.Println(" 3. Default (embedded) - built-in defaults")
156+
157+
msg, _ := assets.GetInitSuccess()
158+
fmt.Println(msg)
160159

161160
return nil
162161
}

cmd/propose.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/fatih/color"
1111
"github.com/spf13/cobra"
1212

13+
"gitmit/assets"
1314
"gitmit/internal/analyzer"
1415
"gitmit/internal/ai"
1516
"gitmit/internal/config"
@@ -267,12 +268,8 @@ func runPropose(cmd *cobra.Command, args []string) error {
267268
finalMessage = aiMsg
268269
usingAI = true
269270
} else {
270-
color.Red("\n⚠️ Ollama connection not detected on %s", cfg.Ollama.URL)
271-
fmt.Println("To enable Local AI generation, please ensure:")
272-
fmt.Println(" 1. Ollama is running locally (`ollama serve`)")
273-
fmt.Printf(" 2. The required model is pulled (`ollama pull %s`)\n", cfg.Ollama.Model)
274-
fmt.Println(" 3. Your .gitmit.json sets \"engine\": \"ollama\"")
275-
fmt.Println("\nFalling back to interactive options...")
271+
warning, _ := assets.RenderOllamaWarning(cfg.Ollama.URL, cfg.Ollama.Model)
272+
color.Red("\n%s", warning)
276273
}
277274
}
278275
continue

internal/ai/prompt.go

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"strings"
77
"text/template"
88

9+
"gitmit/assets"
910
"gitmit/internal/analyzer"
1011
)
1112

@@ -25,28 +26,13 @@ type DiffSummary struct {
2526
Ratio float64
2627
}
2728

28-
const promptTemplate = `You are an expert developer assistant. Analyze the provided structured git diff metadata and generate a single-line commit message following the Conventional Commits specification.
29-
30-
Guidelines:
31-
1. Format MUST be: <type>(<scope>): <short description in present tense>
32-
2. Allowed types: feat, fix, refactor, chore, test, docs, style, perf, ci, build, security
33-
3. Do NOT include any markdown, backticks, quotes, or introductory text like "Here is your commit message:".
34-
4. Output ONLY the raw string of the commit message.
35-
36-
Metadata Context:
37-
- Project Type: {{.ProjectType}}
38-
- Active Branch Name: {{.CurrentBranch}}
39-
- Detected Intent/Type Bonus: {{.RecommendedType}}
40-
- Modified Files: {{range .Files}}{{.}}, {{end}}
41-
- Key Code Symbols Altered: {{range .CodeSymbols}}{{.}}, {{end}}
42-
- Dependency Changes: {{.DependencyAlert}}
43-
- Added/Deleted Line Ratio: {{printf "%.2f" .DiffSummary.Ratio}}
44-
45-
Output:
46-
`
47-
4829
// RenderPrompt generates the prompt string using the provided context
4930
func RenderPrompt(msg *analyzer.CommitMessage, projectType, branchName string) (string, error) {
31+
promptTemplate, err := assets.GetPrompt()
32+
if err != nil {
33+
return "", fmt.Errorf("error loading prompt template: %w", err)
34+
}
35+
5036
tmpl, err := template.New("prompt").Parse(promptTemplate)
5137
if err != nil {
5238
return "", fmt.Errorf("error parsing prompt template: %w", err)

0 commit comments

Comments
 (0)