1use crate::config::AppConfig;
2
3const CONVENTIONAL_COMMIT_SPEC: &str = "\
4Follow the Conventional Commits specification:
5- Prefix with a type: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
6- Optionally add a scope in parentheses: feat(parser):
7- Follow with a colon and space, then a short description
8- Examples: feat: add user login, fix(api): handle null response, docs: update README";
9
10const GITMOJI_UNICODE_SPEC: &str = "\
11Use Gitmoji: start the commit message with a relevant emoji in unicode format.
12Examples: \u{26a1}\u{fe0f} Improve performance, \u{1f41b} Fix bug, \u{2728} Add new feature, \
13\u{267b}\u{fe0f} Refactor code, \u{1f4dd} Update docs, \u{1f3a8} Improve UI";
14
15const GITMOJI_SHORTCODE_SPEC: &str = "\
16Use Gitmoji: start the commit message with a relevant emoji in :shortcode: format.
17Examples: :zap: Improve performance, :bug: Fix bug, :sparkles: Add new feature, \
18:recycle: Refactor code, :memo: Update docs, :art: Improve UI";
19
20pub fn build_system_prompt(cfg: &AppConfig) -> String {
22 let mut parts = Vec::new();
23
24 parts.push(cfg.llm_system_prompt.clone());
26
27 parts.push(CONVENTIONAL_COMMIT_SPEC.to_string());
29
30 if cfg.use_gitmoji {
32 let spec = match cfg.gitmoji_format.as_str() {
33 "shortcode" => GITMOJI_SHORTCODE_SPEC,
34 _ => GITMOJI_UNICODE_SPEC,
35 };
36 parts.push(spec.to_string());
37 }
38
39 if cfg.one_liner {
41 parts.push("Output ONLY a single line. No body, no footer, no explanations.".to_string());
42 }
43
44 if cfg.locale != "en" {
46 parts.push(format!(
47 "Write the commit message in the '{}' locale.",
48 cfg.locale
49 ));
50 }
51
52 parts.push(
54 "Use present tense. Be concise. Output only the raw commit message, nothing else."
55 .to_string(),
56 );
57
58 parts.join("\n\n")
59}