1pub const STANDARD: &str = include_str!("../prompts/standard.md");
9
10pub const SPLIT: &str = include_str!("../prompts/split.md");
12
13pub const VERIFY: &str = include_str!("../prompts/verify.md");
15
16pub const MERGE_CONFLICT: &str = include_str!("../prompts/merge-conflict.md");
18
19pub const PARALLEL_CLEANUP: &str = include_str!("../prompts/parallel-cleanup.md");
21
22pub const OLLAMA: &str = include_str!("../prompts/ollama.md");
24
25#[cfg(debug_assertions)]
27mod dev {
28 pub const BOOTSTRAP: &str = include_str!("../prompts-dev/bootstrap.md");
30
31 pub const DOCUMENTATION: &str = include_str!("../prompts-dev/documentation.md");
33
34 pub const DOC_AUDIT: &str = include_str!("../prompts-dev/doc-audit.md");
36
37 pub const RESEARCH_ANALYSIS: &str = include_str!("../prompts-dev/research-analysis.md");
39
40 pub const RESEARCH_SYNTHESIS: &str = include_str!("../prompts-dev/research-synthesis.md");
42}
43
44#[derive(Debug, Clone)]
46pub struct PromptMetadata {
47 pub name: &'static str,
49 pub purpose: &'static str,
51 pub content: &'static str,
53}
54
55pub fn all_bundled_prompts() -> Vec<PromptMetadata> {
57 let prompts = vec![
58 PromptMetadata {
59 name: "standard",
60 purpose: "Default execution prompt",
61 content: STANDARD,
62 },
63 PromptMetadata {
64 name: "split",
65 purpose: "Split a driver spec into members with detailed acceptance criteria",
66 content: SPLIT,
67 },
68 PromptMetadata {
69 name: "verify",
70 purpose: "Verify that acceptance criteria are met",
71 content: VERIFY,
72 },
73 PromptMetadata {
74 name: "merge-conflict",
75 purpose: "Resolve git merge conflicts during rebase operations",
76 content: MERGE_CONFLICT,
77 },
78 PromptMetadata {
79 name: "parallel-cleanup",
80 purpose: "Analyze parallel execution results and help resolve issues",
81 content: PARALLEL_CLEANUP,
82 },
83 PromptMetadata {
84 name: "ollama",
85 purpose: "Optimized prompt for local LLM execution",
86 content: OLLAMA,
87 },
88 ];
89
90 #[cfg(debug_assertions)]
92 let prompts = {
93 let mut prompts = prompts;
94 prompts.extend(vec![
95 PromptMetadata {
96 name: "bootstrap",
97 purpose: "Minimal bootstrap prompt that defers to prep command",
98 content: dev::BOOTSTRAP,
99 },
100 PromptMetadata {
101 name: "documentation",
102 purpose: "Generate documentation from tracked source files",
103 content: dev::DOCUMENTATION,
104 },
105 PromptMetadata {
106 name: "doc-audit",
107 purpose: "Audit Rust code against mdbook documentation",
108 content: dev::DOC_AUDIT,
109 },
110 PromptMetadata {
111 name: "research-analysis",
112 purpose: "Chant-specific research analysis",
113 content: dev::RESEARCH_ANALYSIS,
114 },
115 PromptMetadata {
116 name: "research-synthesis",
117 purpose: "Chant-specific research synthesis",
118 content: dev::RESEARCH_SYNTHESIS,
119 },
120 ]);
121 prompts
122 };
123
124 prompts
125}
126
127pub fn get_prompt(name: &str) -> Option<PromptMetadata> {
129 all_bundled_prompts().into_iter().find(|p| p.name == name)
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 #[test]
137 fn test_all_bundled_prompts_not_empty() {
138 let prompts = all_bundled_prompts();
139 assert!(!prompts.is_empty());
140 }
141
142 #[test]
143 fn test_all_prompts_have_content() {
144 let prompts = all_bundled_prompts();
145 for prompt in prompts {
146 assert!(
147 !prompt.content.is_empty(),
148 "Prompt {} has no content",
149 prompt.name
150 );
151 }
152 }
153
154 #[test]
155 #[cfg(debug_assertions)]
156 fn test_get_prompt_bootstrap() {
157 let prompt = get_prompt("bootstrap");
158 assert!(prompt.is_some());
159 let p = prompt.unwrap();
160 assert_eq!(p.name, "bootstrap");
161 assert!(p.content.contains("chant prep"));
162 }
163
164 #[test]
165 fn test_get_prompt_nonexistent() {
166 let prompt = get_prompt("nonexistent");
167 assert!(prompt.is_none());
168 }
169}