Skip to main content

auto_commit_rs/
prompt.rs

1use crate::config::AppConfig;
2
3const CONVENTIONAL_COMMIT_SPEC: &str = "\
4Write all commit messages strictly following the Conventional Commits specification.
5
6Use the following format:
7<type>[optional scope][optional !]: <description>
8
9[optional body]
10
11[optional footer(s)]
12
13Rules to follow:
141. Type: MUST be a noun. Use `feat` for new features, `fix` for bug fixes, or other relevant types (e.g., `docs`, `chore`, `refactor`).
152. Scope: OPTIONAL. A noun describing the affected section of the codebase, enclosed in parentheses (e.g., `fix(parser):`).
163. Description: REQUIRED. A concise summary immediately following the type/scope, colon, and space.
174. Body: OPTIONAL. Provide additional context. MUST begin one blank line after the description.
185. Footer: OPTIONAL. MUST begin one blank line after the body. Use token-value pairs (e.g., `Reviewed-by: Name`). Token words must be hyphenated.
196. Breaking Changes: MUST be indicated by either an exclamation mark `!` immediately before the colon (e.g., `feat!:`) OR an uppercase `BREAKING CHANGE: <description>` in the footer.";
20
21const GITMOJI_UNICODE_SPEC: &str = "\
22Use Gitmoji while still following the Conventional Commits specification above: \
23prepend a relevant emoji in unicode format, then a space, then the conventional type(scope): description. \
24Examples: \u{26a1}\u{fe0f} feat(api): improve response time, \u{1f41b} fix(auth): correct login redirect, \
25\u{2728} feat: add new feature, \u{267b}\u{fe0f} refactor(parser): simplify logic, \u{1f4dd} docs: update README, \u{1f3a8} style(ui): improve layout";
26
27const GITMOJI_SHORTCODE_SPEC: &str = "\
28Use Gitmoji while still following the Conventional Commits specification above: \
29prepend a relevant emoji in :shortcode: format, then a space, then the conventional type(scope): description. \
30Examples: :zap: feat(api): improve response time, :bug: fix(auth): correct login redirect, \
31:sparkles: feat: add new feature, :recycle: refactor(parser): simplify logic, :memo: docs: update README, :art: style(ui): improve layout";
32
33/// Build the full system prompt from config flags
34pub fn build_system_prompt(cfg: &AppConfig) -> String {
35    let mut parts = Vec::new();
36
37    // Base prompt (user-overridable)
38    parts.push(cfg.llm_system_prompt.clone());
39
40    // Conventional commits
41    parts.push(CONVENTIONAL_COMMIT_SPEC.to_string());
42
43    // Gitmoji
44    if cfg.use_gitmoji {
45        let spec = match cfg.gitmoji_format.as_str() {
46            "shortcode" => GITMOJI_SHORTCODE_SPEC,
47            _ => GITMOJI_UNICODE_SPEC,
48        };
49        parts.push(spec.to_string());
50    }
51
52    // One-liner
53    if cfg.one_liner {
54        parts.push("Craft a concise, single sentence, commit message that encapsulates all changes made, with an emphasis on the primary updates. If the modifications share a common theme or scope, mention it succinctly; otherwise, leave the scope out to maintain focus. The goal is to provide a clear and unified overview of the changes in one single message.".to_string());
55    }
56
57    // Locale
58    if cfg.locale != "en" {
59        parts.push(format!(
60            "Write the commit message in the '{}' locale.",
61            cfg.locale
62        ));
63    }
64
65    // Universal closing instructions
66    parts.push(
67        "Use present tense. Be concise. Output only the raw commit message, nothing else."
68            .to_string(),
69    );
70
71    parts.join("\n\n")
72}