1use std::collections::HashMap;
9
10#[derive(Debug, Clone)]
12pub struct EmbeddedTemplate {
13 pub name: &'static str,
15 pub content: &'static str,
17 pub description: &'static str,
19}
20
21#[must_use]
28pub fn get_embedded_template(name: &str) -> Option<String> {
29 EMBEDDED_TEMPLATES.get(name).map(|t| t.content.to_string())
30}
31
32#[must_use]
39#[cfg(test)]
40pub fn get_template_metadata(name: &str) -> Option<&'static EmbeddedTemplate> {
41 EMBEDDED_TEMPLATES.get(name)
42}
43
44#[must_use]
50pub fn list_all_templates() -> Vec<&'static EmbeddedTemplate> {
51 let mut templates: Vec<&EmbeddedTemplate> = EMBEDDED_TEMPLATES.values().collect();
52 templates.sort_by_key(|t| t.name);
53 templates
54}
55
56#[must_use]
60pub fn get_templates_map() -> HashMap<String, (String, String)> {
61 let mut map = HashMap::new();
62 for template in list_all_templates() {
63 map.insert(
64 template.name.to_string(),
65 (
66 template.content.to_string(),
67 template.description.to_string(),
68 ),
69 );
70 }
71 map
72}
73
74static EMBEDDED_TEMPLATES: std::sync::LazyLock<HashMap<&str, EmbeddedTemplate>> =
83 std::sync::LazyLock::new(|| {
84 let mut m = HashMap::new();
85
86 m.insert(
91 "commit_message_xml",
92 EmbeddedTemplate {
93 name: "commit_message_xml",
94 content: include_str!("templates/commit_message_xml.txt"),
95 description: "Generate Conventional Commits messages from git diffs (XML format)",
96 },
97 );
98
99 m.insert(
100 "commit_strict_json",
101 EmbeddedTemplate {
102 name: "commit_strict_json",
103 content: include_str!("templates/commit_strict_json.txt"),
104 description: "Strict JSON commit message format (retry attempt 1)",
105 },
106 );
107
108 m.insert(
109 "commit_strict_json_v2",
110 EmbeddedTemplate {
111 name: "commit_strict_json_v2",
112 content: include_str!("templates/commit_strict_json_v2.txt"),
113 description: "Strict JSON commit message format with examples (retry attempt 2)",
114 },
115 );
116
117 m.insert(
118 "commit_ultra_minimal",
119 EmbeddedTemplate {
120 name: "commit_ultra_minimal",
121 content: include_str!("templates/commit_ultra_minimal.txt"),
122 description: "Ultra-minimal commit message prompt (retry attempt 3)",
123 },
124 );
125
126 m.insert(
127 "commit_ultra_minimal_v2",
128 EmbeddedTemplate {
129 name: "commit_ultra_minimal_v2",
130 content: include_str!("templates/commit_ultra_minimal_v2.txt"),
131 description: "Ultra-minimal commit message prompt v2 (retry attempt 4)",
132 },
133 );
134
135 m.insert(
136 "commit_file_list_only",
137 EmbeddedTemplate {
138 name: "commit_file_list_only",
139 content: include_str!("templates/commit_file_list_only.txt"),
140 description: "Commit message from file list only (fallback 1)",
141 },
142 );
143
144 m.insert(
145 "commit_file_list_summary",
146 EmbeddedTemplate {
147 name: "commit_file_list_summary",
148 content: include_str!("templates/commit_file_list_summary.txt"),
149 description: "Commit message from file summary (fallback 2)",
150 },
151 );
152
153 m.insert(
154 "commit_emergency",
155 EmbeddedTemplate {
156 name: "commit_emergency",
157 content: include_str!("templates/commit_emergency.txt"),
158 description: "Emergency commit message with diff (fallback 3)",
159 },
160 );
161
162 m.insert(
163 "commit_emergency_no_diff",
164 EmbeddedTemplate {
165 name: "commit_emergency_no_diff",
166 content: include_str!("templates/commit_emergency_no_diff.txt"),
167 description: "Emergency commit message without diff (last resort)",
168 },
169 );
170
171 m.insert(
172 "commit_message_fallback",
173 EmbeddedTemplate {
174 name: "commit_message_fallback",
175 content: include_str!("templates/commit_message_fallback.txt"),
176 description: "Fallback commit message template",
177 },
178 );
179
180 m.insert(
185 "developer_iteration",
186 EmbeddedTemplate {
187 name: "developer_iteration",
188 content: include_str!("templates/developer_iteration.txt"),
189 description: "Developer agent implementation mode prompt",
190 },
191 );
192
193 m.insert(
194 "planning",
195 EmbeddedTemplate {
196 name: "planning",
197 content: include_str!("templates/planning.txt"),
198 description: "Planning phase prompt for implementation plans",
199 },
200 );
201
202 m.insert(
203 "developer_iteration_fallback",
204 EmbeddedTemplate {
205 name: "developer_iteration_fallback",
206 content: include_str!("templates/developer_iteration_fallback.txt"),
207 description: "Fallback developer iteration prompt",
208 },
209 );
210
211 m.insert(
212 "planning_fallback",
213 EmbeddedTemplate {
214 name: "planning_fallback",
215 content: include_str!("templates/planning_fallback.txt"),
216 description: "Fallback planning prompt",
217 },
218 );
219
220 m.insert(
225 "fix_mode",
226 EmbeddedTemplate {
227 name: "fix_mode",
228 content: include_str!("templates/fix_mode.txt"),
229 description: "Fix mode prompt for addressing review issues",
230 },
231 );
232
233 m.insert(
234 "fix_mode_fallback",
235 EmbeddedTemplate {
236 name: "fix_mode_fallback",
237 content: include_str!("templates/fix_mode_fallback.txt"),
238 description: "Fallback fix mode prompt",
239 },
240 );
241
242 m.insert(
247 "conflict_resolution",
248 EmbeddedTemplate {
249 name: "conflict_resolution",
250 content: include_str!("templates/conflict_resolution.txt"),
251 description: "Merge conflict resolution prompt",
252 },
253 );
254
255 m.insert(
256 "conflict_resolution_fallback",
257 EmbeddedTemplate {
258 name: "conflict_resolution_fallback",
259 content: include_str!("templates/conflict_resolution_fallback.txt"),
260 description: "Fallback conflict resolution prompt",
261 },
262 );
263
264 m.insert(
269 "detailed_review_minimal",
270 EmbeddedTemplate {
271 name: "detailed_review_minimal",
272 content: include_str!("reviewer/templates/detailed_review_minimal.txt"),
273 description: "Detailed review mode (minimal context)",
274 },
275 );
276
277 m.insert(
278 "detailed_review_normal",
279 EmbeddedTemplate {
280 name: "detailed_review_normal",
281 content: include_str!("reviewer/templates/detailed_review_normal.txt"),
282 description: "Detailed review mode (normal context)",
283 },
284 );
285
286 m.insert(
287 "incremental_review_minimal",
288 EmbeddedTemplate {
289 name: "incremental_review_minimal",
290 content: include_str!("reviewer/templates/incremental_review_minimal.txt"),
291 description: "Incremental review (changed files only, minimal context)",
292 },
293 );
294
295 m.insert(
296 "incremental_review_normal",
297 EmbeddedTemplate {
298 name: "incremental_review_normal",
299 content: include_str!("reviewer/templates/incremental_review_normal.txt"),
300 description: "Incremental review (changed files only, normal context)",
301 },
302 );
303
304 m.insert(
305 "universal_review_minimal",
306 EmbeddedTemplate {
307 name: "universal_review_minimal",
308 content: include_str!("reviewer/templates/universal_review_minimal.txt"),
309 description: "Universal review (all file types, minimal context)",
310 },
311 );
312
313 m.insert(
314 "universal_review_normal",
315 EmbeddedTemplate {
316 name: "universal_review_normal",
317 content: include_str!("reviewer/templates/universal_review_normal.txt"),
318 description: "Universal review (all file types, normal context)",
319 },
320 );
321
322 m.insert(
323 "standard_review_minimal",
324 EmbeddedTemplate {
325 name: "standard_review_minimal",
326 content: include_str!("reviewer/templates/standard_review_minimal.txt"),
327 description: "Standard review (balanced, minimal context)",
328 },
329 );
330
331 m.insert(
332 "standard_review_normal",
333 EmbeddedTemplate {
334 name: "standard_review_normal",
335 content: include_str!("reviewer/templates/standard_review_normal.txt"),
336 description: "Standard review (balanced, normal context)",
337 },
338 );
339
340 m.insert(
341 "comprehensive_review_minimal",
342 EmbeddedTemplate {
343 name: "comprehensive_review_minimal",
344 content: include_str!("reviewer/templates/comprehensive_review_minimal.txt"),
345 description: "Comprehensive review (thorough, minimal context)",
346 },
347 );
348
349 m.insert(
350 "comprehensive_review_normal",
351 EmbeddedTemplate {
352 name: "comprehensive_review_normal",
353 content: include_str!("reviewer/templates/comprehensive_review_normal.txt"),
354 description: "Comprehensive review (thorough, normal context)",
355 },
356 );
357
358 m.insert(
359 "security_review_minimal",
360 EmbeddedTemplate {
361 name: "security_review_minimal",
362 content: include_str!("reviewer/templates/security_review_minimal.txt"),
363 description: "Security-focused review (OWASP, minimal context)",
364 },
365 );
366
367 m.insert(
368 "security_review_normal",
369 EmbeddedTemplate {
370 name: "security_review_normal",
371 content: include_str!("reviewer/templates/security_review_normal.txt"),
372 description: "Security-focused review (OWASP, normal context)",
373 },
374 );
375
376 m
377 });
378
379#[cfg(test)]
380mod tests {
381 use super::*;
382
383 #[test]
384 fn test_get_embedded_template_existing() {
385 let result = get_embedded_template("developer_iteration");
386 assert!(result.is_some());
387 let content = result.unwrap();
388 assert!(!content.is_empty());
389 assert!(content.contains("IMPLEMENTATION MODE") || content.contains("Developer"));
390 }
391
392 #[test]
393 fn test_get_embedded_template_not_found() {
394 let result = get_embedded_template("nonexistent_template");
395 assert!(result.is_none());
396 }
397
398 #[test]
399 fn test_get_template_metadata() {
400 let metadata = get_template_metadata("commit_message_xml");
401 assert!(metadata.is_some());
402 let template = metadata.unwrap();
403 assert_eq!(template.name, "commit_message_xml");
404 assert!(!template.description.is_empty());
405 }
406
407 #[test]
408 fn test_list_all_templates() {
409 let templates = list_all_templates();
410 assert!(!templates.is_empty());
411 assert!(templates.len() >= 20); for window in templates.windows(2) {
415 assert!(window[0].name <= window[1].name);
416 }
417 }
418
419 #[test]
420 fn test_get_templates_map() {
421 let map = get_templates_map();
422 assert!(!map.is_empty());
423 assert!(map.contains_key("developer_iteration"));
424 assert!(map.contains_key("commit_message_xml"));
425
426 let (content, description) = map.get("developer_iteration").unwrap();
427 assert!(!content.is_empty());
428 assert!(!description.is_empty());
429 }
430
431 #[test]
432 fn test_all_templates_have_content() {
433 let templates = list_all_templates();
434 for template in templates {
435 assert!(
436 !template.content.is_empty(),
437 "Template '{}' has empty content",
438 template.name
439 );
440 }
441 }
442
443 #[test]
444 fn test_all_templates_have_descriptions() {
445 let templates = list_all_templates();
446 for template in templates {
447 assert!(
448 !template.description.is_empty(),
449 "Template '{}' has empty description",
450 template.name
451 );
452 }
453 }
454
455 #[test]
456 fn test_fallback_templates_exist() {
457 assert!(get_embedded_template("developer_iteration_fallback").is_some());
459 assert!(get_embedded_template("planning_fallback").is_some());
460 assert!(get_embedded_template("fix_mode_fallback").is_some());
461 assert!(get_embedded_template("conflict_resolution_fallback").is_some());
462 assert!(get_embedded_template("commit_message_fallback").is_some());
463 }
464}