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
33pub fn build_system_prompt(cfg: &AppConfig) -> String {
35 let mut parts = Vec::new();
36
37 parts.push(cfg.llm_system_prompt.clone());
39
40 parts.push(CONVENTIONAL_COMMIT_SPEC.to_string());
42
43 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 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 if cfg.locale != "en" {
59 parts.push(format!(
60 "Write the commit message in the '{}' locale.",
61 cfg.locale
62 ));
63 }
64
65 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}