Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions internal/config/assets/conventional.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,3 @@ Rules:
- Describe the breaking change clearly in the footer using "BREAKING CHANGE:"
- If useful, add a body explaining *why* the change was made, not just what changed
- Wrap body lines at approximately 72 characters
- Do not mention the diff, filenames, or line numbers explicitly
- Do not wrap the message in backticks or code fences
- Output only the commit message, with no extra commentary

Write the commit message based on the following git diff:
5 changes: 0 additions & 5 deletions internal/config/assets/default.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,3 @@ Rules:
- Use full sentences and paragraphs as needed

- Do not include metadata such as timestamps or author names
- Do not mention the diff, file names, or line numbers explicitly
- Do not wrap the message in backticks or code fences
- Output only the commit message, with no additional explanations

Write the commit message based on the following git diff:
5 changes: 0 additions & 5 deletions internal/config/assets/gitmoji.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,3 @@ Rules:
- Use only one emoji per commit
- Do not include Conventional Commits types (feat, fix, etc.)
- Do not mix multiple conventions in a single commit
- Do not mention the diff, file names, or line numbers explicitly
- Do not wrap the message in backticks or code fences
- Output only the commit message, with no explanations or metadata

Write the commit message based on the following git diff:
6 changes: 0 additions & 6 deletions internal/config/assets/karma.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,3 @@ Rules:
- If the change introduces a breaking change:
- Use BREAKING CHANGE in the footer
- The subject must describe the change, not the migration steps

- Do not reference the diff, file names, or line numbers directly
- Do not wrap the message in backticks or code fences
- Output only the commit message, without any explanations or metadata

Write the commit message based on the following git diff:
39 changes: 26 additions & 13 deletions internal/prompt/prompt.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
package prompt

import "strings"
import (
"bytes"
_ "embed"
"strings"
"text/template"
)

//go:embed prompt.tmpl
var promptTemplateText string

var promptTemplate = template.Must(template.New("prompt").Parse(promptTemplateText))

type PromptData struct {
SystemPrompt string
Context string
Diff string
}

func Build(systemPrompt, context, diff string) string {
var b strings.Builder
if systemPrompt != "" {
b.WriteString("System Prompt:\n")
b.WriteString(systemPrompt)
b.WriteString("\n\n")
data := PromptData{
SystemPrompt: strings.TrimSpace(systemPrompt),
Context: strings.TrimSpace(context),
Diff: diff,
}
if context != "" {
b.WriteString("Context:\n")
b.WriteString(context)
b.WriteString("\n\n")
var buf bytes.Buffer
if err := promptTemplate.Execute(&buf, data); err != nil {
// Fallback to simple concatenation on template error
return systemPrompt + "\n\n" + context + "\n\n" + diff
}
b.WriteString("Git Diff:\n")
b.WriteString(diff)
return b.String()
return buf.String()
}
19 changes: 19 additions & 0 deletions internal/prompt/prompt.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
=== INSTRUCTIONS ===
{{.SystemPrompt}}

OUTPUT RULES:
- Output only a Git commit message
- Begin with the commit subject line
- Exclude explanations, preambles, and meta commentary
- DO NOT reference diffs, file names, or line numbers
- DO NOT use code fences or backticks

{{if .Context}}
=== CONTEXT ===
{{.Context}}
{{end}}

=== GIT DIFF ===
{{.Diff}}

=== OUTPUT ===
60 changes: 56 additions & 4 deletions internal/prompt/prompt_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,63 @@
package prompt

import "testing"
import (
"strings"
"testing"
)

func TestBuild(t *testing.T) {
got := Build("sys", "ctx", "diff")
expected := "System Prompt:\nsys\n\nContext:\nctx\n\nGit Diff:\ndiff"
if got != expected {
t.Fatalf("Build = %q", got)

// Check that output contains expected sections
if !strings.Contains(got, "=== INSTRUCTIONS ===") {
t.Fatal("Build output should contain INSTRUCTIONS section")
}
if !strings.Contains(got, "sys") {
t.Fatal("Build output should contain system prompt")
}
if !strings.Contains(got, "OUTPUT RULES:") {
t.Fatal("Build output should contain OUTPUT RULES section")
}
if !strings.Contains(got, "=== CONTEXT ===") {
t.Fatal("Build output should contain CONTEXT section when context provided")
}
if !strings.Contains(got, "ctx") {
t.Fatal("Build output should contain context content")
}
if !strings.Contains(got, "=== GIT DIFF ===") {
t.Fatal("Build output should contain GIT DIFF section")
}
if !strings.Contains(got, "diff") {
t.Fatal("Build output should contain diff content")
}
if !strings.Contains(got, "=== OUTPUT ===") {
t.Fatal("Build output should contain OUTPUT section")
}
}

func TestBuildWithoutContext(t *testing.T) {
got := Build("sys", "", "diff")

// Check that output omits CONTEXT section when empty
if strings.Contains(got, "=== CONTEXT ===") {
t.Fatal("Build output should not contain CONTEXT section when context is empty")
}
if !strings.Contains(got, "=== INSTRUCTIONS ===") {
t.Fatal("Build output should contain INSTRUCTIONS section")
}
if !strings.Contains(got, "=== GIT DIFF ===") {
t.Fatal("Build output should contain GIT DIFF section")
}
}

func TestBuildOutputRules(t *testing.T) {
got := Build("sys", "ctx", "diff")

// Verify output rules are included
if !strings.Contains(got, "Exclude explanations, preambles") {
t.Fatal("Build output should contain preamble suppression rule")
}
if !strings.Contains(got, "Begin with the commit subject line") {
t.Fatal("Build output should contain direct start instruction")
}
}