22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
# File 'lib/ai_git/default.rb', line 22
def generate_commit_message(diff, model_name)
raise "No staged changes to generate commit message for" if diff.to_s.strip.empty?
prompt = <<~PROMPT
You are an expert Git commit message writer. Output ONLY the commit message — no explanations, no markdown, no backticks, no preamble.
Here are the changes:
#{diff}
STRICT OUTPUT FORMAT (follow exactly):
<short imperative title, max 72 chars>
<blank line>
## Summary
<2–4 bullet points covering the most important changes. Each bullet starts with a verb.>
## Why
<1–3 sentences explaining the motivation or context behind the change. Omit if the reason is obvious.>
RULES:
- Title line: short, specific, imperative mood (e.g. "Add JWT login with refresh token support"). Avoid vague titles like "Update stuff" or "Fix bug".
- Summary bullets: describe WHAT changed, not HOW the code looks. Focus on behaviour and impact.
- Why section: explain the problem being solved or the goal being achieved. Skip if it adds no value.
- No filler phrases ("this commit", "this PR", "as per discussion").
- No line should exceed 72 characters.
EXAMPLES OF GOOD OUTPUT:
Add JWT-based login with refresh token support
## Summary
- Implement login endpoint with access and refresh token issuance
- Add token refresh route with rotation and expiry validation
- Protect private routes via middleware that verifies access tokens
- Store refresh tokens using encrypted HTTP-only cookies
## Why
Users were being logged out on every page reload. Refresh tokens allow
sessions to persist securely without requiring re-authentication.
---
Prevent nil crash when user preferences are missing
## Summary
- Add nil guard in ReportGenerator#process before accessing preferences
- Fall back to system defaults when preferences object is absent
## Why
Reports were raising NoMethodError in production for users created
before the preferences feature shipped.
---
Now generate the commit message:
PROMPT
json_body = {
model: model_name,
prompt: prompt,
stream: false,
temperature: 0.3,
top_p: 0.9,
stop: ["\n\n\n", "```", "Here is", "The commit message"],
num_predict: 400
}.to_json
uri = URI("http://localhost:11434/api/generate")
request = Net::HTTP::Post.new(uri)
request["Content-Type"] = "application/json"
request.body = json_body
response = Net::HTTP.start(uri.host, uri.port, read_timeout: 120) do |http|
http.request(request)
end
raise "Failed to connect to Ollama. Is it running?" unless response.is_a?(Net::HTTPSuccess)
data = JSON.parse(response.body)
message = data["response"].to_s.strip
message = message.gsub(/^(Here is|The commit message is|```|json|markdown)/i, "")
.gsub(/^>\s*/, "")
.gsub(/\\n/, "\n")
.strip
lines = message.lines.map(&:strip)
lines.reject! { |line| line.match?(/^(Here|Output|Generated|Based on|The changes)/i) }
message = lines.join("\n").strip
message = "chore: update code" if message.lines.count < 1 || message.strip.empty?
message
end
|