codeprism_mcp/
prompts.rs

1//! MCP Prompts implementation
2//!
3//! Prompts allow servers to provide structured messages and instructions for
4//! interacting with language models. Clients can discover available prompts,
5//! retrieve their contents, and provide arguments to customize them.
6
7use crate::CodePrismMcpServer;
8use anyhow::Result;
9use serde::{Deserialize, Serialize};
10use serde_json::Value;
11
12/// Prompt capabilities as defined by MCP
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct PromptCapabilities {
15    /// Whether the server will emit notifications when the list of available prompts changes
16    #[serde(rename = "listChanged")]
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub list_changed: Option<bool>,
19}
20
21/// MCP Prompt definition
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct Prompt {
24    /// Unique identifier for the prompt
25    pub name: String,
26    /// Optional human-readable title for display purposes
27    #[serde(skip_serializing_if = "Option::is_none")]
28    pub title: Option<String>,
29    /// Human-readable description of the prompt
30    pub description: String,
31    /// Optional arguments schema for the prompt
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub arguments: Option<Vec<PromptArgument>>,
34}
35
36/// Prompt argument definition
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct PromptArgument {
39    /// Argument name
40    pub name: String,
41    /// Human-readable description
42    pub description: String,
43    /// Whether the argument is required
44    pub required: bool,
45}
46
47/// Prompt message content
48#[derive(Debug, Clone, Serialize, Deserialize)]
49pub struct PromptMessage {
50    /// Role of the message (user, assistant, system)
51    pub role: String,
52    /// Content of the message
53    pub content: PromptContent,
54}
55
56/// Prompt content types
57#[derive(Debug, Clone, Serialize, Deserialize)]
58#[serde(tag = "type")]
59pub enum PromptContent {
60    /// Text content
61    #[serde(rename = "text")]
62    Text {
63        /// Text content
64        text: String,
65    },
66    /// Image content
67    #[serde(rename = "image")]
68    Image {
69        /// Base64-encoded image data
70        data: String,
71        /// MIME type of the image
72        #[serde(rename = "mimeType")]
73        mime_type: String,
74    },
75}
76
77/// Parameters for getting a prompt
78#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct GetPromptParams {
80    /// Name of the prompt to get
81    pub name: String,
82    /// Optional arguments for the prompt
83    #[serde(skip_serializing_if = "Option::is_none")]
84    pub arguments: Option<serde_json::Map<String, Value>>,
85}
86
87/// Result of getting a prompt
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct GetPromptResult {
90    /// Description of the prompt
91    #[serde(skip_serializing_if = "Option::is_none")]
92    pub description: Option<String>,
93    /// Messages that make up the prompt
94    pub messages: Vec<PromptMessage>,
95}
96
97/// Parameters for listing prompts
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct ListPromptsParams {
100    /// Optional cursor for pagination
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub cursor: Option<String>,
103}
104
105/// Result of listing prompts
106#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct ListPromptsResult {
108    /// List of available prompts
109    pub prompts: Vec<Prompt>,
110    /// Optional cursor for pagination
111    #[serde(rename = "nextCursor")]
112    #[serde(skip_serializing_if = "Option::is_none")]
113    pub next_cursor: Option<String>,
114}
115
116/// Prompt manager for MCP server
117pub struct PromptManager {
118    server: std::sync::Arc<tokio::sync::RwLock<CodePrismMcpServer>>,
119}
120
121impl PromptManager {
122    /// Create a new prompt manager
123    pub fn new(server: std::sync::Arc<tokio::sync::RwLock<CodePrismMcpServer>>) -> Self {
124        Self { server }
125    }
126
127    /// List available prompts
128    pub async fn list_prompts(&self, _params: ListPromptsParams) -> Result<ListPromptsResult> {
129        let prompts = vec![
130            Prompt {
131                name: "repository_overview".to_string(),
132                title: Some("Repository Overview".to_string()),
133                description: "Generate a comprehensive overview of the repository structure and contents".to_string(),
134                arguments: Some(vec![
135                    PromptArgument {
136                        name: "focus_area".to_string(),
137                        description: "Optional area to focus on (architecture, dependencies, entry_points, etc.)".to_string(),
138                        required: false,
139                    },
140                ]),
141            },
142
143            Prompt {
144                name: "code_analysis".to_string(),
145                title: Some("Code Analysis".to_string()),
146                description: "Analyze code quality, patterns, and potential improvements".to_string(),
147                arguments: Some(vec![
148                    PromptArgument {
149                        name: "file_pattern".to_string(),
150                        description: "Optional file pattern to focus analysis on".to_string(),
151                        required: false,
152                    },
153                    PromptArgument {
154                        name: "analysis_type".to_string(),
155                        description: "Type of analysis (quality, security, performance, architecture)".to_string(),
156                        required: false,
157                    },
158                ]),
159            },
160
161            Prompt {
162                name: "debug_assistance".to_string(),
163                title: Some("Debug Assistance".to_string()),
164                description: "Help debug issues in the codebase with contextual information".to_string(),
165                arguments: Some(vec![
166                    PromptArgument {
167                        name: "issue_description".to_string(),
168                        description: "Description of the issue or error".to_string(),
169                        required: true,
170                    },
171                    PromptArgument {
172                        name: "affected_files".to_string(),
173                        description: "Files related to the issue".to_string(),
174                        required: false,
175                    },
176                ]),
177            },
178
179            Prompt {
180                name: "debug_issue".to_string(),
181                title: Some("Debug Issue".to_string()),
182                description: "Analyze potential bug sources and dependencies for debugging".to_string(),
183                arguments: Some(vec![
184                    PromptArgument {
185                        name: "error_location".to_string(),
186                        description: "File and line where error occurs".to_string(),
187                        required: true,
188                    },
189                    PromptArgument {
190                        name: "error_message".to_string(),
191                        description: "Error message or description".to_string(),
192                        required: false,
193                    },
194                ]),
195            },
196
197            Prompt {
198                name: "refactoring_guidance".to_string(),
199                title: Some("Refactoring Guidance".to_string()),
200                description: "Provide guidance for refactoring code with repository context".to_string(),
201                arguments: Some(vec![
202                    PromptArgument {
203                        name: "target_area".to_string(),
204                        description: "Area of code to refactor".to_string(),
205                        required: true,
206                    },
207                    PromptArgument {
208                        name: "refactoring_goal".to_string(),
209                        description: "Goal of the refactoring (performance, maintainability, etc.)".to_string(),
210                        required: false,
211                    },
212                ]),
213            },
214
215            Prompt {
216                name: "architectural_analysis".to_string(),
217                title: Some("Architectural Analysis".to_string()),
218                description: "Analyze the overall architecture, patterns, and structural design of the codebase".to_string(),
219                arguments: Some(vec![
220                    PromptArgument {
221                        name: "analysis_focus".to_string(),
222                        description: "Focus area for analysis (layers, patterns, dependencies, coupling)".to_string(),
223                        required: false,
224                    },
225                    PromptArgument {
226                        name: "architectural_concerns".to_string(),
227                        description: "Specific architectural concerns or questions".to_string(),
228                        required: false,
229                    },
230                ]),
231            },
232
233            Prompt {
234                name: "pattern_assessment".to_string(),
235                title: Some("Design Pattern Assessment".to_string()),
236                description: "Assess design patterns usage and suggest architectural improvements".to_string(),
237                arguments: Some(vec![
238                    PromptArgument {
239                        name: "pattern_types".to_string(),
240                        description: "Types of patterns to focus on (design_patterns, anti_patterns, architectural_patterns)".to_string(),
241                        required: false,
242                    },
243                    PromptArgument {
244                        name: "improvement_scope".to_string(),
245                        description: "Scope of improvements to suggest (immediate, long-term, strategic)".to_string(),
246                        required: false,
247                    },
248                ]),
249            },
250
251            Prompt {
252                name: "dependency_analysis".to_string(),
253                title: Some("Dependency Analysis".to_string()),
254                description: "Analyze dependencies, coupling, and suggest decoupling strategies".to_string(),
255                arguments: Some(vec![
256                    PromptArgument {
257                        name: "analysis_target".to_string(),
258                        description: "Target for analysis (file, class, module, or repository-wide)".to_string(),
259                        required: false,
260                    },
261                    PromptArgument {
262                        name: "dependency_concerns".to_string(),
263                        description: "Specific dependency concerns (cycles, coupling, cohesion)".to_string(),
264                        required: false,
265                    },
266                ]),
267            },
268
269            // New prompt templates for large codebase understanding
270            Prompt {
271                name: "new_developer_onboarding".to_string(),
272                title: Some("New Developer Onboarding".to_string()),
273                description: "Create a comprehensive onboarding guide for new developers joining the project".to_string(),
274                arguments: Some(vec![
275                    PromptArgument {
276                        name: "developer_experience".to_string(),
277                        description: "Developer's experience level (junior, mid, senior)".to_string(),
278                        required: false,
279                    },
280                    PromptArgument {
281                        name: "focus_areas".to_string(),
282                        description: "Areas the developer should focus on first (frontend, backend, infrastructure, etc.)".to_string(),
283                        required: false,
284                    },
285                    PromptArgument {
286                        name: "timeline".to_string(),
287                        description: "Onboarding timeline (1-week, 2-week, 1-month)".to_string(),
288                        required: false,
289                    },
290                ]),
291            },
292
293            Prompt {
294                name: "feature_exploration".to_string(),
295                title: Some("Feature Exploration".to_string()),
296                description: "Deep dive into understanding a specific feature or module in the codebase".to_string(),
297                arguments: Some(vec![
298                    PromptArgument {
299                        name: "feature_name".to_string(),
300                        description: "Name or description of the feature to explore".to_string(),
301                        required: true,
302                    },
303                    PromptArgument {
304                        name: "exploration_depth".to_string(),
305                        description: "Depth of exploration (overview, detailed, implementation)".to_string(),
306                        required: false,
307                    },
308                    PromptArgument {
309                        name: "include_tests".to_string(),
310                        description: "Whether to include test coverage analysis".to_string(),
311                        required: false,
312                    },
313                ]),
314            },
315
316            Prompt {
317                name: "learning_path_generator".to_string(),
318                title: Some("Learning Path Generator".to_string()),
319                description: "Generate a guided learning path through the codebase for specific goals".to_string(),
320                arguments: Some(vec![
321                    PromptArgument {
322                        name: "learning_goal".to_string(),
323                        description: "What the user wants to learn or achieve".to_string(),
324                        required: true,
325                    },
326                    PromptArgument {
327                        name: "current_knowledge".to_string(),
328                        description: "User's current knowledge level with the codebase".to_string(),
329                        required: false,
330                    },
331                    PromptArgument {
332                        name: "time_constraint".to_string(),
333                        description: "Available time for learning (1-day, 1-week, 1-month)".to_string(),
334                        required: false,
335                    },
336                ]),
337            },
338
339            Prompt {
340                name: "technology_stack_analysis".to_string(),
341                title: Some("Technology Stack Analysis".to_string()),
342                description: "Analyze the technology stack, frameworks, and architectural decisions".to_string(),
343                arguments: Some(vec![
344                    PromptArgument {
345                        name: "analysis_focus".to_string(),
346                        description: "Focus area (languages, frameworks, tools, infrastructure)".to_string(),
347                        required: false,
348                    },
349                    PromptArgument {
350                        name: "include_alternatives".to_string(),
351                        description: "Whether to suggest alternative technologies".to_string(),
352                        required: false,
353                    },
354                ]),
355            },
356
357            Prompt {
358                name: "codebase_health_check".to_string(),
359                title: Some("Codebase Health Check".to_string()),
360                description: "Comprehensive health assessment of the codebase including quality, maintainability, and technical debt".to_string(),
361                arguments: Some(vec![
362                    PromptArgument {
363                        name: "health_aspects".to_string(),
364                        description: "Aspects to focus on (code_quality, test_coverage, security, performance, maintainability)".to_string(),
365                        required: false,
366                    },
367                    PromptArgument {
368                        name: "severity_threshold".to_string(),
369                        description: "Minimum severity level for issues to report (low, medium, high, critical)".to_string(),
370                        required: false,
371                    },
372                ]),
373            },
374
375            Prompt {
376                name: "documentation_generator".to_string(),
377                title: Some("Documentation Generator".to_string()),
378                description: "Generate comprehensive documentation for the codebase or specific components".to_string(),
379                arguments: Some(vec![
380                    PromptArgument {
381                        name: "documentation_type".to_string(),
382                        description: "Type of documentation (API, architecture, developer_guide, user_manual)".to_string(),
383                        required: true,
384                    },
385                    PromptArgument {
386                        name: "target_audience".to_string(),
387                        description: "Target audience (developers, users, architects, managers)".to_string(),
388                        required: false,
389                    },
390                    PromptArgument {
391                        name: "scope".to_string(),
392                        description: "Scope of documentation (full_repository, specific_module, specific_feature)".to_string(),
393                        required: false,
394                    },
395                ]),
396            },
397
398            Prompt {
399                name: "testing_strategy_analysis".to_string(),
400                title: Some("Testing Strategy Analysis".to_string()),
401                description: "Analyze current testing approach and suggest improvements for test coverage and quality".to_string(),
402                arguments: Some(vec![
403                    PromptArgument {
404                        name: "test_types".to_string(),
405                        description: "Types of tests to analyze (unit, integration, e2e, performance)".to_string(),
406                        required: false,
407                    },
408                    PromptArgument {
409                        name: "coverage_threshold".to_string(),
410                        description: "Minimum coverage threshold to aim for (percentage)".to_string(),
411                        required: false,
412                    },
413                ]),
414            },
415
416            Prompt {
417                name: "migration_planning".to_string(),
418                title: Some("Migration Planning".to_string()),
419                description: "Plan migration strategies for legacy code, frameworks, or architectural changes".to_string(),
420                arguments: Some(vec![
421                    PromptArgument {
422                        name: "migration_type".to_string(),
423                        description: "Type of migration (framework_upgrade, language_migration, architecture_change)".to_string(),
424                        required: true,
425                    },
426                    PromptArgument {
427                        name: "target_technology".to_string(),
428                        description: "Target technology or framework to migrate to".to_string(),
429                        required: false,
430                    },
431                    PromptArgument {
432                        name: "risk_tolerance".to_string(),
433                        description: "Risk tolerance level (low, medium, high)".to_string(),
434                        required: false,
435                    },
436                ]),
437            },
438        ];
439
440        Ok(ListPromptsResult {
441            prompts,
442            next_cursor: None,
443        })
444    }
445
446    /// Get a specific prompt
447    pub async fn get_prompt(&self, params: GetPromptParams) -> Result<GetPromptResult> {
448        let server = self.server.read().await;
449
450        match params.name.as_str() {
451            "repository_overview" => {
452                self.repository_overview_prompt(&server, params.arguments)
453                    .await
454            }
455            "code_analysis" => self.code_analysis_prompt(&server, params.arguments).await,
456            "debug_assistance" => {
457                self.debug_assistance_prompt(&server, params.arguments)
458                    .await
459            }
460            "debug_issue" => self.debug_issue_prompt(&server, params.arguments).await,
461            "refactoring_guidance" => {
462                self.refactoring_guidance_prompt(&server, params.arguments)
463                    .await
464            }
465            "architectural_analysis" => {
466                self.architectural_analysis_prompt(&server, params.arguments)
467                    .await
468            }
469            "pattern_assessment" => {
470                self.pattern_assessment_prompt(&server, params.arguments)
471                    .await
472            }
473            "dependency_analysis" => {
474                self.dependency_analysis_prompt(&server, params.arguments)
475                    .await
476            }
477            "new_developer_onboarding" => {
478                self.new_developer_onboarding_prompt(&server, params.arguments)
479                    .await
480            }
481            "feature_exploration" => {
482                self.feature_exploration_prompt(&server, params.arguments)
483                    .await
484            }
485            "learning_path_generator" => {
486                self.learning_path_generator_prompt(&server, params.arguments)
487                    .await
488            }
489            "technology_stack_analysis" => {
490                self.technology_stack_analysis_prompt(&server, params.arguments)
491                    .await
492            }
493            "codebase_health_check" => {
494                self.codebase_health_check_prompt(&server, params.arguments)
495                    .await
496            }
497            "documentation_generator" => {
498                self.documentation_generator_prompt(&server, params.arguments)
499                    .await
500            }
501            "testing_strategy_analysis" => {
502                self.testing_strategy_analysis_prompt(&server, params.arguments)
503                    .await
504            }
505            "migration_planning" => {
506                self.migration_planning_prompt(&server, params.arguments)
507                    .await
508            }
509            _ => Err(anyhow::anyhow!("Unknown prompt: {}", params.name)),
510        }
511    }
512
513    /// Generate repository overview prompt
514    async fn repository_overview_prompt(
515        &self,
516        server: &CodePrismMcpServer,
517        arguments: Option<serde_json::Map<String, Value>>,
518    ) -> Result<GetPromptResult> {
519        let focus_area = arguments
520            .as_ref()
521            .and_then(|args| args.get("focus_area"))
522            .and_then(|v| v.as_str())
523            .unwrap_or("general");
524
525        let repo_context = if let Some(repo_path) = server.repository_path() {
526            let file_count = server
527                .scanner()
528                .discover_files(repo_path)
529                .map(|files| files.len())
530                .unwrap_or(0);
531
532            format!(
533                "Repository: {}\nTotal files: {}\nFocus area: {}",
534                repo_path.display(),
535                file_count,
536                focus_area
537            )
538        } else {
539            "No repository currently loaded".to_string()
540        };
541
542        let prompt_text = format!(
543            r#"Please provide a comprehensive overview of this repository with the following context:
544
545{}
546
547Please analyze and provide:
5481. Repository structure and organization
5492. Main technologies and frameworks used
5503. Key entry points and important files
5514. Dependencies and external libraries
5525. Code patterns and architectural decisions
5536. Areas for potential improvement
554
555Focus particularly on: {}
556
557Use the repository resources and tools available to gather detailed information about the codebase."#,
558            repo_context, focus_area
559        );
560
561        Ok(GetPromptResult {
562            description: Some("Repository overview and analysis prompt".to_string()),
563            messages: vec![PromptMessage {
564                role: "user".to_string(),
565                content: PromptContent::Text { text: prompt_text },
566            }],
567        })
568    }
569
570    /// Generate code analysis prompt
571    async fn code_analysis_prompt(
572        &self,
573        server: &CodePrismMcpServer,
574        arguments: Option<serde_json::Map<String, Value>>,
575    ) -> Result<GetPromptResult> {
576        let file_pattern = arguments
577            .as_ref()
578            .and_then(|args| args.get("file_pattern"))
579            .and_then(|v| v.as_str())
580            .unwrap_or("*");
581
582        let analysis_type = arguments
583            .as_ref()
584            .and_then(|args| args.get("analysis_type"))
585            .and_then(|v| v.as_str())
586            .unwrap_or("quality");
587
588        let repo_context = if let Some(repo_path) = server.repository_path() {
589            format!("Repository: {}", repo_path.display())
590        } else {
591            "No repository currently loaded".to_string()
592        };
593
594        let prompt_text = format!(
595            r#"Please perform a {} analysis of the codebase with the following context:
596
597{}
598
599File pattern: {}
600Analysis focus: {}
601
602Please analyze and provide:
6031. Code quality assessment
6042. Potential issues and vulnerabilities
6053. Best practices compliance
6064. Performance considerations
6075. Maintainability factors
6086. Specific recommendations for improvement
609
610Use the available tools to gather detailed information about the code structure and patterns."#,
611            analysis_type, repo_context, file_pattern, analysis_type
612        );
613
614        Ok(GetPromptResult {
615            description: Some("Code analysis and quality assessment prompt".to_string()),
616            messages: vec![PromptMessage {
617                role: "user".to_string(),
618                content: PromptContent::Text { text: prompt_text },
619            }],
620        })
621    }
622
623    /// Generate debug assistance prompt
624    async fn debug_assistance_prompt(
625        &self,
626        _server: &CodePrismMcpServer,
627        arguments: Option<serde_json::Map<String, Value>>,
628    ) -> Result<GetPromptResult> {
629        let issue_description = arguments
630            .as_ref()
631            .and_then(|args| args.get("issue_description"))
632            .and_then(|v| v.as_str())
633            .ok_or_else(|| anyhow::anyhow!("issue_description argument is required"))?;
634
635        let affected_files = arguments
636            .as_ref()
637            .and_then(|args| args.get("affected_files"))
638            .and_then(|v| v.as_str())
639            .unwrap_or("unknown");
640
641        let prompt_text = format!(
642            r#"I need help debugging the following issue:
643
644Issue Description: {}
645Affected Files: {}
646
647Please help me:
6481. Understand the root cause of this issue
6492. Identify related code that might be contributing to the problem
6503. Suggest debugging steps and approaches
6514. Provide potential solutions or workarounds
6525. Recommend best practices to prevent similar issues
653
654Use the repository tools to examine the relevant code and dependencies."#,
655            issue_description, affected_files
656        );
657
658        Ok(GetPromptResult {
659            description: Some("Debug assistance with repository context".to_string()),
660            messages: vec![PromptMessage {
661                role: "user".to_string(),
662                content: PromptContent::Text { text: prompt_text },
663            }],
664        })
665    }
666
667    /// Generate debug issue prompt
668    async fn debug_issue_prompt(
669        &self,
670        _server: &CodePrismMcpServer,
671        arguments: Option<serde_json::Map<String, Value>>,
672    ) -> Result<GetPromptResult> {
673        let error_location = arguments
674            .as_ref()
675            .and_then(|args| args.get("error_location"))
676            .and_then(|v| v.as_str())
677            .ok_or_else(|| anyhow::anyhow!("error_location argument is required"))?;
678
679        let error_message = arguments
680            .as_ref()
681            .and_then(|args| args.get("error_message"))
682            .and_then(|v| v.as_str())
683            .unwrap_or("No error message provided");
684
685        let prompt_text = format!(
686            r#"Please analyze the following error:
687
688Error Location: {}
689Error Message: {}
690
691Please provide:
6921. Analysis of the error's source and potential impact
6932. Suggestions for debugging and resolving the issue
6943. Recommendations for preventing similar errors in the future
695
696Use the repository tools to understand the code and dependencies related to this error."#,
697            error_location, error_message
698        );
699
700        Ok(GetPromptResult {
701            description: Some("Debug issue analysis prompt".to_string()),
702            messages: vec![PromptMessage {
703                role: "user".to_string(),
704                content: PromptContent::Text { text: prompt_text },
705            }],
706        })
707    }
708
709    /// Generate refactoring guidance prompt
710    async fn refactoring_guidance_prompt(
711        &self,
712        _server: &CodePrismMcpServer,
713        arguments: Option<serde_json::Map<String, Value>>,
714    ) -> Result<GetPromptResult> {
715        let target_area = arguments
716            .as_ref()
717            .and_then(|args| args.get("target_area"))
718            .and_then(|v| v.as_str())
719            .ok_or_else(|| anyhow::anyhow!("target_area argument is required"))?;
720
721        let refactoring_goal = arguments
722            .as_ref()
723            .and_then(|args| args.get("refactoring_goal"))
724            .and_then(|v| v.as_str())
725            .unwrap_or("improve maintainability");
726
727        let prompt_text = format!(
728            r#"I need guidance for refactoring the following area of the codebase:
729
730Target Area: {}
731Refactoring Goal: {}
732
733Please provide:
7341. Analysis of the current code structure and patterns
7352. Identification of code smells or areas for improvement
7363. Recommended refactoring approach and strategy
7374. Step-by-step refactoring plan
7385. Potential risks and mitigation strategies
7396. Testing considerations during refactoring
740
741Use the repository tools to understand the current implementation and its dependencies."#,
742            target_area, refactoring_goal
743        );
744
745        Ok(GetPromptResult {
746            description: Some("Refactoring guidance with repository analysis".to_string()),
747            messages: vec![PromptMessage {
748                role: "user".to_string(),
749                content: PromptContent::Text { text: prompt_text },
750            }],
751        })
752    }
753
754    /// Generate architectural analysis prompt
755    async fn architectural_analysis_prompt(
756        &self,
757        _server: &CodePrismMcpServer,
758        arguments: Option<serde_json::Map<String, Value>>,
759    ) -> Result<GetPromptResult> {
760        let analysis_focus = arguments
761            .as_ref()
762            .and_then(|args| args.get("analysis_focus"))
763            .and_then(|v| v.as_str())
764            .unwrap_or("general");
765
766        let prompt_text = format!(
767            r#"Please analyze the overall architecture, patterns, and structural design of the codebase with the following focus:
768
769{}
770
771Please provide:
7721. Analysis of the current architecture
7732. Identification of architectural concerns or questions
7743. Suggestions for architectural improvements
7754. Step-by-step plan for implementing improvements
7765. Potential risks and mitigation strategies
7776. Testing considerations during architectural changes
778
779Use the repository tools to understand the current implementation and its dependencies."#,
780            analysis_focus
781        );
782
783        Ok(GetPromptResult {
784            description: Some("Architectural analysis prompt".to_string()),
785            messages: vec![PromptMessage {
786                role: "user".to_string(),
787                content: PromptContent::Text { text: prompt_text },
788            }],
789        })
790    }
791
792    /// Generate pattern assessment prompt
793    async fn pattern_assessment_prompt(
794        &self,
795        _server: &CodePrismMcpServer,
796        arguments: Option<serde_json::Map<String, Value>>,
797    ) -> Result<GetPromptResult> {
798        let pattern_types = arguments
799            .as_ref()
800            .and_then(|args| args.get("pattern_types"))
801            .and_then(|v| v.as_str())
802            .unwrap_or("general");
803
804        let _improvement_scope = arguments
805            .as_ref()
806            .and_then(|args| args.get("improvement_scope"))
807            .and_then(|v| v.as_str())
808            .unwrap_or("general");
809
810        let prompt_text = format!(
811            r#"Please assess the usage of design patterns in the codebase with the following focus:
812
813{}
814
815Please provide:
8161. Analysis of the current pattern usage
8172. Identification of patterns that could be improved
8183. Suggestions for architectural improvements based on pattern usage
8194. Step-by-step plan for implementing improvements
8205. Potential risks and mitigation strategies
8216. Testing considerations during architectural changes
822
823Use the repository tools to understand the current implementation and its dependencies."#,
824            pattern_types
825        );
826
827        Ok(GetPromptResult {
828            description: Some("Design pattern assessment prompt".to_string()),
829            messages: vec![PromptMessage {
830                role: "user".to_string(),
831                content: PromptContent::Text { text: prompt_text },
832            }],
833        })
834    }
835
836    /// Generate dependency analysis prompt
837    async fn dependency_analysis_prompt(
838        &self,
839        _server: &CodePrismMcpServer,
840        arguments: Option<serde_json::Map<String, Value>>,
841    ) -> Result<GetPromptResult> {
842        let _analysis_target = arguments
843            .as_ref()
844            .and_then(|args| args.get("analysis_target"))
845            .and_then(|v| v.as_str())
846            .unwrap_or("general");
847
848        let dependency_concerns = arguments
849            .as_ref()
850            .and_then(|args| args.get("dependency_concerns"))
851            .and_then(|v| v.as_str())
852            .unwrap_or("general");
853
854        let prompt_text = format!(
855            r#"Please analyze dependencies, coupling, and suggest decoupling strategies with the following focus:
856
857{}
858
859Please provide:
8601. Analysis of the current dependency structure
8612. Identification of dependency concerns
8623. Suggestions for decoupling strategies
8634. Step-by-step plan for implementing improvements
8645. Potential risks and mitigation strategies
8656. Testing considerations during architectural changes
866
867Use the repository tools to understand the current implementation and its dependencies."#,
868            dependency_concerns
869        );
870
871        Ok(GetPromptResult {
872            description: Some("Dependency analysis prompt".to_string()),
873            messages: vec![PromptMessage {
874                role: "user".to_string(),
875                content: PromptContent::Text { text: prompt_text },
876            }],
877        })
878    }
879
880    /// Generate new developer onboarding prompt
881    async fn new_developer_onboarding_prompt(
882        &self,
883        server: &CodePrismMcpServer,
884        arguments: Option<serde_json::Map<String, Value>>,
885    ) -> Result<GetPromptResult> {
886        let developer_experience = arguments
887            .as_ref()
888            .and_then(|args| args.get("developer_experience"))
889            .and_then(|v| v.as_str())
890            .unwrap_or("mid");
891
892        let focus_areas = arguments
893            .as_ref()
894            .and_then(|args| args.get("focus_areas"))
895            .and_then(|v| v.as_str())
896            .unwrap_or("general");
897
898        let timeline = arguments
899            .as_ref()
900            .and_then(|args| args.get("timeline"))
901            .and_then(|v| v.as_str())
902            .unwrap_or("2-week");
903
904        let repo_context = if let Some(repo_path) = server.repository_path() {
905            format!("Repository: {}", repo_path.display())
906        } else {
907            "No repository currently loaded".to_string()
908        };
909
910        let prompt_text = format!(
911            r#"Please create a comprehensive onboarding guide for a new {} developer joining this project:
912
913{}
914
915Developer experience level: {}
916Focus areas: {}
917Onboarding timeline: {}
918
919Please provide:
9201. **Repository Overview**: Structure, key directories, and important files
9212. **Technology Stack**: Languages, frameworks, tools, and dependencies
9223. **Development Environment Setup**: Step-by-step setup instructions
9234. **Architecture Understanding**: High-level architecture and design patterns
9245. **Key Features Walkthrough**: Main features and how they work
9256. **Development Workflow**: Coding standards, testing, and deployment processes
9267. **First Tasks**: Suggested starter tasks to get familiar with the codebase
9278. **Learning Resources**: Documentation, wiki, and helpful references
9289. **Team Contacts**: Who to contact for different areas/questions
92910. **Success Metrics**: How to measure onboarding progress
930
931Use repository analysis tools to gather detailed information about:
932- File structure and organization
933- Dependencies and external libraries
934- Code patterns and conventions
935- Test coverage and quality
936- Documentation availability
937
938Tailor the guide to the developer's experience level and focus areas."#,
939            developer_experience, repo_context, developer_experience, focus_areas, timeline
940        );
941
942        Ok(GetPromptResult {
943            description: Some("Comprehensive new developer onboarding guide".to_string()),
944            messages: vec![PromptMessage {
945                role: "user".to_string(),
946                content: PromptContent::Text { text: prompt_text },
947            }],
948        })
949    }
950
951    /// Generate feature exploration prompt
952    async fn feature_exploration_prompt(
953        &self,
954        server: &CodePrismMcpServer,
955        arguments: Option<serde_json::Map<String, Value>>,
956    ) -> Result<GetPromptResult> {
957        let feature_name = arguments
958            .as_ref()
959            .and_then(|args| args.get("feature_name"))
960            .and_then(|v| v.as_str())
961            .ok_or_else(|| anyhow::anyhow!("feature_name argument is required"))?;
962
963        let exploration_depth = arguments
964            .as_ref()
965            .and_then(|args| args.get("exploration_depth"))
966            .and_then(|v| v.as_str())
967            .unwrap_or("detailed");
968
969        let include_tests = arguments
970            .as_ref()
971            .and_then(|args| args.get("include_tests"))
972            .and_then(|v| v.as_str())
973            .unwrap_or("true");
974
975        let repo_context = if let Some(repo_path) = server.repository_path() {
976            format!("Repository: {}", repo_path.display())
977        } else {
978            "No repository currently loaded".to_string()
979        };
980
981        let prompt_text = format!(
982            r#"Please provide a comprehensive exploration of the '{}' feature in this codebase:
983
984{}
985
986Exploration depth: {}
987Include test analysis: {}
988
989Please analyze and provide:
990
9911. **Feature Overview**:
992   - Purpose and functionality of the feature
993   - Business value and user impact
994   - High-level architecture
995
9962. **Code Structure**:
997   - Main files and directories related to the feature
998   - Key classes, functions, and modules
999   - Entry points and public APIs
1000
10013. **Implementation Details**:
1002   - Core algorithms and logic
1003   - Data models and structures
1004   - External dependencies and integrations
1005
10064. **Dependencies and Relationships**:
1007   - Dependencies on other features/modules
1008   - Features that depend on this one
1009   - External library dependencies
1010
10115. **Data Flow**:
1012   - How data flows through the feature
1013   - Input/output interfaces
1014   - State management
1015
10166. **Configuration and Settings**:
1017   - Configuration options
1018   - Environment variables
1019   - Feature flags or toggles
1020
1021{}
1022
10237. **Documentation and Comments**:
1024   - Existing documentation
1025   - Code comments and explanations
1026   - Missing documentation areas
1027
10288. **Potential Issues and Improvements**:
1029   - Code quality concerns
1030   - Performance considerations
1031   - Security implications
1032   - Refactoring opportunities
1033
1034Use repository analysis tools to:
1035- Search for relevant files and symbols
1036- Analyze dependencies and references
1037- Examine code patterns and complexity
1038- Trace execution paths
1039
1040Provide specific file paths, function names, and code examples where relevant."#,
1041            feature_name,
1042            repo_context,
1043            exploration_depth,
1044            include_tests,
1045            if include_tests == "true" {
1046                "\n7. **Test Coverage**:\n   - Existing test files and test cases\n   - Test coverage analysis\n   - Test quality and completeness\n   - Missing test scenarios"
1047            } else {
1048                ""
1049            }
1050        );
1051
1052        Ok(GetPromptResult {
1053            description: Some("Comprehensive feature exploration and analysis".to_string()),
1054            messages: vec![PromptMessage {
1055                role: "user".to_string(),
1056                content: PromptContent::Text { text: prompt_text },
1057            }],
1058        })
1059    }
1060
1061    /// Generate learning path generator prompt
1062    async fn learning_path_generator_prompt(
1063        &self,
1064        server: &CodePrismMcpServer,
1065        arguments: Option<serde_json::Map<String, Value>>,
1066    ) -> Result<GetPromptResult> {
1067        let learning_goal = arguments
1068            .as_ref()
1069            .and_then(|args| args.get("learning_goal"))
1070            .and_then(|v| v.as_str())
1071            .ok_or_else(|| anyhow::anyhow!("learning_goal argument is required"))?;
1072
1073        let current_knowledge = arguments
1074            .as_ref()
1075            .and_then(|args| args.get("current_knowledge"))
1076            .and_then(|v| v.as_str())
1077            .unwrap_or("beginner");
1078
1079        let time_constraint = arguments
1080            .as_ref()
1081            .and_then(|args| args.get("time_constraint"))
1082            .and_then(|v| v.as_str())
1083            .unwrap_or("1-week");
1084
1085        let repo_context = if let Some(repo_path) = server.repository_path() {
1086            format!("Repository: {}", repo_path.display())
1087        } else {
1088            "No repository currently loaded".to_string()
1089        };
1090
1091        let prompt_text = format!(
1092            r#"Please create a personalized learning path for the following goal:
1093
1094**Learning Goal**: {}
1095**Current Knowledge Level**: {}
1096**Time Available**: {}
1097**Repository Context**: {}
1098
1099Please create a structured learning path that includes:
1100
11011. **Learning Objectives**:
1102   - Specific, measurable goals
1103   - Prerequisites and assumptions
1104   - Success criteria
1105
11062. **Phased Learning Plan**:
1107   - Phase 1: Foundation (understanding basics)
1108   - Phase 2: Core Concepts (deeper understanding)
1109   - Phase 3: Advanced Topics (mastery and application)
1110   - Phase 4: Practical Application (hands-on work)
1111
11123. **Daily/Weekly Schedule**:
1113   - Time allocation for each phase
1114   - Daily learning tasks
1115   - Milestone checkpoints
1116
11174. **Resource Identification**:
1118   - Key files to study (prioritized list)
1119   - Important functions/classes to understand
1120   - Relevant documentation and comments
1121   - External resources if needed
1122
11235. **Hands-on Exercises**:
1124   - Specific code reading exercises
1125   - Small modification tasks
1126   - Debugging exercises
1127   - Code tracing activities
1128
11296. **Assessment Methods**:
1130   - Self-assessment questions
1131   - Practical challenges
1132   - Code review criteria
1133
11347. **Common Pitfalls and Tips**:
1135   - Areas that are typically confusing
1136   - Best practices to follow
1137   - Debugging strategies
1138
1139Use repository analysis tools to:
1140- Identify the most relevant files and functions for the learning goal
1141- Map dependencies and relationships
1142- Assess code complexity to sequence learning appropriately
1143- Find examples and test cases
1144
1145Adjust the complexity and pace based on the current knowledge level and time constraints."#,
1146            learning_goal, current_knowledge, time_constraint, repo_context
1147        );
1148
1149        Ok(GetPromptResult {
1150            description: Some("Personalized learning path through the codebase".to_string()),
1151            messages: vec![PromptMessage {
1152                role: "user".to_string(),
1153                content: PromptContent::Text { text: prompt_text },
1154            }],
1155        })
1156    }
1157
1158    /// Generate technology stack analysis prompt
1159    async fn technology_stack_analysis_prompt(
1160        &self,
1161        server: &CodePrismMcpServer,
1162        arguments: Option<serde_json::Map<String, Value>>,
1163    ) -> Result<GetPromptResult> {
1164        let analysis_focus = arguments
1165            .as_ref()
1166            .and_then(|args| args.get("analysis_focus"))
1167            .and_then(|v| v.as_str())
1168            .unwrap_or("comprehensive");
1169
1170        let include_alternatives = arguments
1171            .as_ref()
1172            .and_then(|args| args.get("include_alternatives"))
1173            .and_then(|v| v.as_str())
1174            .unwrap_or("false");
1175
1176        let repo_context = if let Some(repo_path) = server.repository_path() {
1177            format!("Repository: {}", repo_path.display())
1178        } else {
1179            "No repository currently loaded".to_string()
1180        };
1181
1182        let prompt_text = format!(
1183            r#"Please analyze the technology stack and architectural decisions in this codebase:
1184
1185{}
1186
1187Analysis focus: {}
1188Include alternatives: {}
1189
1190Please provide a comprehensive analysis covering:
1191
11921. **Programming Languages**:
1193   - Primary and secondary languages used
1194   - Language versions and compatibility
1195   - Language-specific patterns and idioms
1196
11972. **Frameworks and Libraries**:
1198   - Web frameworks (if applicable)
1199   - Testing frameworks
1200   - Utility libraries and their purposes
1201   - Version information and update status
1202
12033. **Development Tools**:
1204   - Build systems and task runners
1205   - Package managers and dependency management
1206   - Code quality tools (linters, formatters)
1207   - Development environment setup
1208
12094. **Infrastructure and Deployment**:
1210   - Deployment strategies and tools
1211   - Containerization (Docker, etc.)
1212   - CI/CD pipeline tools
1213   - Cloud services and platforms
1214
12155. **Data Storage and Management**:
1216   - Database technologies
1217   - Data modeling approaches
1218   - Caching strategies
1219   - Data migration tools
1220
12216. **Architecture Patterns**:
1222   - Architectural styles (MVC, microservices, etc.)
1223   - Design patterns in use
1224   - Communication patterns (REST, GraphQL, etc.)
1225   - Event handling and messaging
1226
12277. **Security Technologies**:
1228   - Authentication and authorization frameworks
1229   - Security libraries and tools
1230   - Encryption and hashing methods
1231
12328. **Performance and Monitoring**:
1233   - Performance monitoring tools
1234   - Logging frameworks
1235   - Metrics and analytics tools
1236
1237{}
1238
12399. **Technology Assessment**:
1240   - Strengths of current technology choices
1241   - Potential limitations or technical debt
1242   - Compatibility and integration concerns
1243   - Maintenance and support considerations
1244
124510. **Recommendations**:
1246    - Technology upgrade suggestions
1247    - Missing tools or frameworks
1248    - Best practices alignment
1249    - Future-proofing considerations
1250
1251Use repository analysis tools to:
1252- Examine configuration files (package.json, requirements.txt, etc.)
1253- Analyze import statements and dependencies
1254- Review build and deployment scripts
1255- Assess code patterns and conventions
1256
1257Provide specific examples and file references where relevant."#,
1258            repo_context,
1259            analysis_focus,
1260            include_alternatives,
1261            if include_alternatives == "true" {
1262                "\n8. **Alternative Technology Considerations**:\n   - Alternative frameworks or libraries\n   - Trade-offs and migration considerations\n   - Emerging technologies relevant to the project\n   - Cost-benefit analysis of alternatives"
1263            } else {
1264                ""
1265            }
1266        );
1267
1268        Ok(GetPromptResult {
1269            description: Some("Comprehensive technology stack analysis".to_string()),
1270            messages: vec![PromptMessage {
1271                role: "user".to_string(),
1272                content: PromptContent::Text { text: prompt_text },
1273            }],
1274        })
1275    }
1276
1277    /// Generate codebase health check prompt
1278    async fn codebase_health_check_prompt(
1279        &self,
1280        server: &CodePrismMcpServer,
1281        arguments: Option<serde_json::Map<String, Value>>,
1282    ) -> Result<GetPromptResult> {
1283        let health_aspects = arguments
1284            .as_ref()
1285            .and_then(|args| args.get("health_aspects"))
1286            .and_then(|v| v.as_str())
1287            .unwrap_or("comprehensive");
1288
1289        let severity_threshold = arguments
1290            .as_ref()
1291            .and_then(|args| args.get("severity_threshold"))
1292            .and_then(|v| v.as_str())
1293            .unwrap_or("medium");
1294
1295        let repo_context = if let Some(repo_path) = server.repository_path() {
1296            format!("Repository: {}", repo_path.display())
1297        } else {
1298            "No repository currently loaded".to_string()
1299        };
1300
1301        let prompt_text = format!(
1302            r#"Please perform a comprehensive health assessment of this codebase:
1303
1304{}
1305
1306Health aspects to focus on: {}
1307Minimum severity threshold: {}
1308
1309Please analyze and provide:
1310
13111. **Code Quality Metrics**:
1312   - Code complexity analysis (cyclomatic, cognitive)
1313   - Code duplication detection
1314   - Code style and consistency
1315   - Documentation coverage
1316
13172. **Maintainability Assessment**:
1318   - Code organization and structure
1319   - Naming conventions and clarity
1320   - Function and class size appropriateness
1321   - Coupling and cohesion analysis
1322
13233. **Technical Debt Analysis**:
1324   - Identified code smells and anti-patterns
1325   - Legacy code sections requiring attention
1326   - Architecture inconsistencies
1327   - Performance bottlenecks
1328
13294. **Security Assessment**:
1330   - Security vulnerability scan
1331   - Authentication and authorization review
1332   - Data handling and privacy concerns
1333   - Dependency security analysis
1334
13355. **Test Coverage and Quality**:
1336   - Test coverage percentage and gaps
1337   - Test quality and effectiveness
1338   - Test maintenance issues
1339   - Testing strategy evaluation
1340
13416. **Dependency Management**:
1342   - Outdated dependencies and security risks
1343   - Dependency conflicts and compatibility
1344   - Unused dependencies
1345   - License compliance review
1346
13477. **Performance Indicators**:
1348   - Performance hot spots and bottlenecks
1349   - Memory usage patterns
1350   - Algorithmic complexity issues
1351   - Scalability concerns
1352
13538. **Documentation Health**:
1354   - API documentation completeness
1355   - Code comment quality and coverage
1356   - Architecture documentation
1357   - User and developer guides
1358
13599. **Development Process Health**:
1360   - Build system reliability
1361   - CI/CD pipeline effectiveness
1362   - Code review practices
1363   - Version control hygiene
1364
136510. **Overall Health Score**:
1366    - Weighted health score (0-100)
1367    - Critical issues requiring immediate attention
1368    - Priority improvement recommendations
1369    - Long-term health strategy
1370
1371Use repository analysis tools to:
1372- Calculate complexity metrics
1373- Detect code duplicates and patterns
1374- Analyze dependencies and vulnerabilities
1375- Assess test coverage and quality
1376- Examine security patterns
1377
1378Provide specific examples, file paths, and actionable recommendations.
1379Focus on issues at or above the '{}' severity threshold."#,
1380            repo_context, health_aspects, severity_threshold, severity_threshold
1381        );
1382
1383        Ok(GetPromptResult {
1384            description: Some("Comprehensive codebase health assessment".to_string()),
1385            messages: vec![PromptMessage {
1386                role: "user".to_string(),
1387                content: PromptContent::Text { text: prompt_text },
1388            }],
1389        })
1390    }
1391
1392    /// Generate documentation generator prompt
1393    async fn documentation_generator_prompt(
1394        &self,
1395        server: &CodePrismMcpServer,
1396        arguments: Option<serde_json::Map<String, Value>>,
1397    ) -> Result<GetPromptResult> {
1398        let documentation_type = arguments
1399            .as_ref()
1400            .and_then(|args| args.get("documentation_type"))
1401            .and_then(|v| v.as_str())
1402            .ok_or_else(|| anyhow::anyhow!("documentation_type argument is required"))?;
1403
1404        let target_audience = arguments
1405            .as_ref()
1406            .and_then(|args| args.get("target_audience"))
1407            .and_then(|v| v.as_str())
1408            .unwrap_or("developers");
1409
1410        let scope = arguments
1411            .as_ref()
1412            .and_then(|args| args.get("scope"))
1413            .and_then(|v| v.as_str())
1414            .unwrap_or("full_repository");
1415
1416        let repo_context = if let Some(repo_path) = server.repository_path() {
1417            format!("Repository: {}", repo_path.display())
1418        } else {
1419            "No repository currently loaded".to_string()
1420        };
1421
1422        let (doc_sections, specific_guidance) = match documentation_type {
1423            "API" => (
1424                vec![
1425                    "API Overview and Purpose",
1426                    "Authentication and Authorization",
1427                    "Endpoint Documentation",
1428                    "Request/Response Schemas",
1429                    "Error Handling",
1430                    "Rate Limiting and Pagination",
1431                    "Code Examples and SDKs",
1432                    "Versioning and Compatibility"
1433                ],
1434                "Focus on public APIs, endpoints, data models, and integration examples. Include OpenAPI/Swagger specs if applicable."
1435            ),
1436            "architecture" => (
1437                vec![
1438                    "System Overview and Context",
1439                    "Architecture Diagrams",
1440                    "Component Descriptions",
1441                    "Data Flow and Interactions",
1442                    "Design Patterns and Principles",
1443                    "Technology Stack",
1444                    "Deployment Architecture",
1445                    "Security Architecture"
1446                ],
1447                "Focus on high-level system design, component interactions, and architectural decisions."
1448            ),
1449            "developer_guide" => (
1450                vec![
1451                    "Getting Started Guide",
1452                    "Development Environment Setup",
1453                    "Project Structure",
1454                    "Coding Standards and Guidelines",
1455                    "Build and Deployment Process",
1456                    "Testing Guidelines",
1457                    "Debugging and Troubleshooting",
1458                    "Contributing Guidelines"
1459                ],
1460                "Focus on practical information for developers working on the codebase."
1461            ),
1462            "user_manual" => (
1463                vec![
1464                    "Introduction and Overview",
1465                    "Installation Instructions",
1466                    "Basic Usage and Tutorials",
1467                    "Feature Documentation",
1468                    "Configuration Options",
1469                    "Troubleshooting Guide",
1470                    "FAQ and Common Issues",
1471                    "Support and Resources"
1472                ],
1473                "Focus on end-user perspective, practical usage, and problem-solving."
1474            ),
1475            _ => (
1476                vec![
1477                    "Project Overview",
1478                    "Architecture and Design",
1479                    "API Documentation",
1480                    "Development Guide",
1481                    "User Instructions"
1482                ],
1483                "Provide comprehensive documentation covering all aspects."
1484            )
1485        };
1486
1487        let sections_text = doc_sections
1488            .iter()
1489            .enumerate()
1490            .map(|(i, section)| format!("{}. **{}**", i + 1, section))
1491            .collect::<Vec<_>>()
1492            .join("\n   ");
1493
1494        let prompt_text = format!(
1495            r#"Please generate comprehensive {} documentation for this codebase:
1496
1497{}
1498
1499Documentation type: {}
1500Target audience: {}
1501Scope: {}
1502
1503Please create documentation with the following structure:
1504
1505   {}
1506
1507**Specific Guidance**: {}
1508
1509**Documentation Requirements**:
1510- Clear, concise, and well-structured content
1511- Appropriate level of technical detail for the target audience
1512- Code examples and practical usage scenarios
1513- Visual aids where helpful (diagrams, flowcharts)
1514- Cross-references and navigation aids
1515- Up-to-date and accurate information
1516
1517**Content Guidelines**:
1518- Use clear headings and subheadings
1519- Include table of contents for longer documents
1520- Provide code examples with explanations
1521- Include troubleshooting sections where relevant
1522- Add links to related resources
1523- Use consistent formatting and style
1524
1525Use repository analysis tools to:
1526- Examine code structure and organization
1527- Extract API definitions and schemas
1528- Analyze dependencies and integrations
1529- Review existing documentation and comments
1530- Understand data models and interfaces
1531- Identify key features and functionalities
1532
1533Ensure the documentation is:
1534- Accurate and reflects the current codebase
1535- Complete within the specified scope
1536- Appropriately detailed for the target audience
1537- Professionally formatted and easy to navigate
1538- Include specific file paths and code references where helpful"#,
1539            documentation_type,
1540            repo_context,
1541            documentation_type,
1542            target_audience,
1543            scope,
1544            sections_text,
1545            specific_guidance
1546        );
1547
1548        Ok(GetPromptResult {
1549            description: Some(format!(
1550                "Generate {} documentation for {}",
1551                documentation_type, target_audience
1552            )),
1553            messages: vec![PromptMessage {
1554                role: "user".to_string(),
1555                content: PromptContent::Text { text: prompt_text },
1556            }],
1557        })
1558    }
1559
1560    /// Generate testing strategy analysis prompt
1561    async fn testing_strategy_analysis_prompt(
1562        &self,
1563        server: &CodePrismMcpServer,
1564        arguments: Option<serde_json::Map<String, Value>>,
1565    ) -> Result<GetPromptResult> {
1566        let test_types = arguments
1567            .as_ref()
1568            .and_then(|args| args.get("test_types"))
1569            .and_then(|v| v.as_str())
1570            .unwrap_or("comprehensive");
1571
1572        let coverage_threshold = arguments
1573            .as_ref()
1574            .and_then(|args| args.get("coverage_threshold"))
1575            .and_then(|v| v.as_str())
1576            .unwrap_or("80");
1577
1578        let repo_context = if let Some(repo_path) = server.repository_path() {
1579            format!("Repository: {}", repo_path.display())
1580        } else {
1581            "No repository currently loaded".to_string()
1582        };
1583
1584        let prompt_text = format!(
1585            r#"Please analyze the current testing strategy and provide recommendations for improvement:
1586
1587{}
1588
1589Test types to analyze: {}
1590Target coverage threshold: {}%
1591
1592Please provide a comprehensive testing analysis:
1593
15941. **Current Testing Overview**:
1595   - Existing test files and structure
1596   - Testing frameworks and tools in use
1597   - Test types currently implemented
1598   - Overall test coverage statistics
1599
16002. **Test Coverage Analysis**:
1601   - Line coverage, branch coverage, function coverage
1602   - Coverage gaps and untested areas
1603   - Critical paths without adequate testing
1604   - High-risk areas requiring more tests
1605
16063. **Test Quality Assessment**:
1607   - Test case effectiveness and completeness
1608   - Test maintenance and readability
1609   - Test data management and setup
1610   - Assertion quality and specificity
1611
16124. **Testing Strategy Evaluation**:
1613   - Unit testing strategy and coverage
1614   - Integration testing approach
1615   - End-to-end testing implementation
1616   - Performance and load testing
1617   - Security testing considerations
1618
16195. **Test Organization and Structure**:
1620   - Test file organization and naming
1621   - Test helper utilities and shared code
1622   - Test configuration and environment setup
1623   - Test data management strategies
1624
16256. **Testing Tools and Infrastructure**:
1626   - Testing framework effectiveness
1627   - CI/CD integration and automation
1628   - Test reporting and metrics
1629   - Test environment management
1630
16317. **Testing Best Practices Compliance**:
1632   - Test isolation and independence
1633   - Test naming and documentation
1634   - Mock and stub usage
1635   - Test pyramid adherence
1636
16378. **Identified Issues and Gaps**:
1638   - Missing test scenarios
1639   - Flaky or unreliable tests
1640   - Slow or inefficient tests
1641   - Maintenance bottlenecks
1642
16439. **Improvement Recommendations**:
1644   - Prioritized list of testing improvements
1645   - New test types to implement
1646   - Testing tool upgrades or changes
1647   - Process and workflow improvements
1648
164910. **Implementation Roadmap**:
1650    - Short-term quick wins
1651    - Medium-term strategic improvements
1652    - Long-term testing vision
1653    - Resource and time estimates
1654
1655Use repository analysis tools to:
1656- Identify all test files and patterns
1657- Analyze test coverage and gaps
1658- Examine testing frameworks and dependencies
1659- Review test organization and structure
1660- Assess test complexity and maintainability
1661
1662Provide specific examples, file paths, and actionable recommendations to reach the {}% coverage threshold."#,
1663            repo_context, test_types, coverage_threshold, coverage_threshold
1664        );
1665
1666        Ok(GetPromptResult {
1667            description: Some(
1668                "Comprehensive testing strategy analysis and recommendations".to_string(),
1669            ),
1670            messages: vec![PromptMessage {
1671                role: "user".to_string(),
1672                content: PromptContent::Text { text: prompt_text },
1673            }],
1674        })
1675    }
1676
1677    /// Generate migration planning prompt
1678    async fn migration_planning_prompt(
1679        &self,
1680        server: &CodePrismMcpServer,
1681        arguments: Option<serde_json::Map<String, Value>>,
1682    ) -> Result<GetPromptResult> {
1683        let migration_type = arguments
1684            .as_ref()
1685            .and_then(|args| args.get("migration_type"))
1686            .and_then(|v| v.as_str())
1687            .ok_or_else(|| anyhow::anyhow!("migration_type argument is required"))?;
1688
1689        let target_technology = arguments
1690            .as_ref()
1691            .and_then(|args| args.get("target_technology"))
1692            .and_then(|v| v.as_str())
1693            .unwrap_or("not specified");
1694
1695        let risk_tolerance = arguments
1696            .as_ref()
1697            .and_then(|args| args.get("risk_tolerance"))
1698            .and_then(|v| v.as_str())
1699            .unwrap_or("medium");
1700
1701        let repo_context = if let Some(repo_path) = server.repository_path() {
1702            format!("Repository: {}", repo_path.display())
1703        } else {
1704            "No repository currently loaded".to_string()
1705        };
1706
1707        let (migration_focus, specific_considerations) = match migration_type {
1708            "framework_upgrade" => (
1709                "Framework Version Upgrade",
1710                "Focus on breaking changes, deprecated features, and compatibility issues.",
1711            ),
1712            "language_migration" => (
1713                "Programming Language Migration",
1714                "Focus on language differences, ecosystem changes, and tooling requirements.",
1715            ),
1716            "architecture_change" => (
1717                "Architectural Transformation",
1718                "Focus on structural changes, component redesign, and system interactions.",
1719            ),
1720            _ => (
1721                "General Migration",
1722                "Focus on identifying migration requirements and planning approach.",
1723            ),
1724        };
1725
1726        let prompt_text = format!(
1727            r#"Please create a comprehensive migration plan for this {} project:
1728
1729{}
1730
1731Migration type: {}
1732Target technology: {}
1733Risk tolerance: {}
1734
1735**Migration Planning Overview**:
1736{}
1737
1738Please provide a detailed migration strategy:
1739
17401. **Current State Analysis**:
1741   - Current technology stack and versions
1742   - Dependencies and external integrations
1743   - Code structure and architectural patterns
1744   - Technical debt and legacy components
1745
17462. **Target State Definition**:
1747   - Target technology specifications
1748   - Expected benefits and improvements
1749   - New capabilities and features
1750   - Performance and scalability goals
1751
17523. **Gap Analysis**:
1753   - Compatibility issues and breaking changes
1754   - Features that need redesign or rewriting
1755   - Dependencies requiring updates or replacements
1756   - Infrastructure and tooling changes needed
1757
17584. **Migration Strategy**:
1759   - Recommended migration approach (big bang, incremental, parallel)
1760   - Migration phases and milestones
1761   - Rollback and contingency plans
1762   - Success criteria and validation methods
1763
17645. **Risk Assessment and Mitigation**:
1765   - Technical risks and challenges
1766   - Business continuity considerations
1767   - Resource and timeline risks
1768   - Mitigation strategies for each risk
1769
17706. **Implementation Roadmap**:
1771   - Phase-by-phase implementation plan
1772   - Timeline estimates and dependencies
1773   - Resource requirements and team structure
1774   - Key decision points and checkpoints
1775
17767. **Code Migration Planning**:
1777   - Files and modules requiring changes
1778   - Automated migration tools and scripts
1779   - Manual migration requirements
1780   - Code review and testing strategies
1781
17828. **Testing and Validation**:
1783   - Migration testing strategy
1784   - Regression testing approach
1785   - Performance testing requirements
1786   - User acceptance testing plan
1787
17889. **Deployment and Rollout**:
1789   - Deployment strategy and environments
1790   - Feature flags and gradual rollout
1791   - Monitoring and observability
1792   - Communication and training plans
1793
179410. **Post-Migration Considerations**:
1795    - Cleanup and optimization tasks
1796    - Documentation updates
1797    - Team training and knowledge transfer
1798    - Long-term maintenance considerations
1799
1800Use repository analysis tools to:
1801- Examine current codebase structure and dependencies
1802- Identify migration complexity and effort
1803- Assess code quality and technical debt
1804- Analyze testing coverage and quality
1805- Review architecture and design patterns
1806
1807Tailor recommendations to the {} risk tolerance level.
1808Provide specific file references, code examples, and actionable steps."#,
1809            migration_focus,
1810            repo_context,
1811            migration_type,
1812            target_technology,
1813            risk_tolerance,
1814            specific_considerations,
1815            risk_tolerance
1816        );
1817
1818        Ok(GetPromptResult {
1819            description: Some(format!(
1820                "Comprehensive migration planning for {}",
1821                migration_type
1822            )),
1823            messages: vec![PromptMessage {
1824                role: "user".to_string(),
1825                content: PromptContent::Text { text: prompt_text },
1826            }],
1827        })
1828    }
1829}
1830
1831#[cfg(test)]
1832mod tests {
1833    use super::*;
1834
1835    #[test]
1836    fn test_prompt_capabilities() {
1837        let capabilities = PromptCapabilities {
1838            list_changed: Some(false),
1839        };
1840
1841        assert_eq!(capabilities.list_changed, Some(false));
1842    }
1843
1844    #[test]
1845    fn test_prompt_serialization() {
1846        let prompt = Prompt {
1847            name: "test_prompt".to_string(),
1848            title: Some("Test Prompt".to_string()),
1849            description: "A test prompt".to_string(),
1850            arguments: Some(vec![PromptArgument {
1851                name: "test_arg".to_string(),
1852                description: "A test argument".to_string(),
1853                required: true,
1854            }]),
1855        };
1856
1857        let json = serde_json::to_string(&prompt).unwrap();
1858        let deserialized: Prompt = serde_json::from_str(&json).unwrap();
1859
1860        assert_eq!(prompt.name, deserialized.name);
1861        assert_eq!(prompt.title, deserialized.title);
1862        assert_eq!(prompt.description, deserialized.description);
1863    }
1864
1865    #[test]
1866    fn test_prompt_content_text() {
1867        let content = PromptContent::Text {
1868            text: "Hello, world!".to_string(),
1869        };
1870
1871        let json = serde_json::to_string(&content).unwrap();
1872        let deserialized: PromptContent = serde_json::from_str(&json).unwrap();
1873
1874        match deserialized {
1875            PromptContent::Text { text } => assert_eq!(text, "Hello, world!"),
1876            _ => panic!("Expected text content"),
1877        }
1878    }
1879
1880    async fn create_test_server() -> crate::CodePrismMcpServer {
1881        use std::fs;
1882        use tempfile::TempDir;
1883
1884        let temp_dir = TempDir::new().expect("Failed to create temp dir");
1885        let repo_path = temp_dir.path();
1886
1887        // Create test files for prompt testing
1888        fs::write(
1889            repo_path.join("main.py"),
1890            r#"
1891class UserService:
1892    """Service for managing users."""
1893    
1894    def __init__(self, database):
1895        self.database = database
1896    
1897    def authenticate_user(self, username: str, password: str) -> bool:
1898        """Authenticate a user with username and password."""
1899        user = self.database.get_user(username)
1900        if not user:
1901            return False
1902        return user.verify_password(password)
1903    
1904    def create_user(self, username: str, email: str, password: str) -> 'User':
1905        """Create a new user account."""
1906        if self.database.user_exists(username):
1907            raise ValueError("User already exists")
1908        
1909        user = User(username, email, password)
1910        self.database.save_user(user)
1911        return user
1912
1913class User:
1914    """User model representing a system user."""
1915    
1916    def __init__(self, username: str, email: str, password: str):
1917        self.username = username
1918        self.email = email
1919        self.password_hash = self._hash_password(password)
1920    
1921    def verify_password(self, password: str) -> bool:
1922        """Verify the user's password."""
1923        return self._hash_password(password) == self.password_hash
1924    
1925    def _hash_password(self, password: str) -> str:
1926        """Hash a password for storage."""
1927        import hashlib
1928        return hashlib.sha256(password.encode()).hexdigest()
1929"#,
1930        )
1931        .unwrap();
1932
1933        fs::write(
1934            repo_path.join("database.py"),
1935            r#"
1936"""Database interface for the application."""
1937
1938from typing import Optional, List
1939import sqlite3
1940
1941class Database:
1942    """Simple SQLite database interface."""
1943    
1944    def __init__(self, db_path: str):
1945        self.db_path = db_path
1946        self.connection = sqlite3.connect(db_path)
1947        self._create_tables()
1948    
1949    def _create_tables(self) -> None:
1950        """Create necessary database tables."""
1951        cursor = self.connection.cursor()
1952        cursor.execute('''
1953            CREATE TABLE IF NOT EXISTS users (
1954                id INTEGER PRIMARY KEY AUTOINCREMENT,
1955                username TEXT UNIQUE NOT NULL,
1956                email TEXT NOT NULL,
1957                password_hash TEXT NOT NULL
1958            )
1959        ''')
1960        self.connection.commit()
1961    
1962    def get_user(self, username: str) -> Optional['User']:
1963        """Get a user by username."""
1964        cursor = self.connection.cursor()
1965        cursor.execute('SELECT * FROM users WHERE username = ?', (username,))
1966        row = cursor.fetchone()
1967        
1968        if row:
1969            from main import User
1970            return User(row[1], row[2], "")  # Password already hashed
1971        return None
1972    
1973    def user_exists(self, username: str) -> bool:
1974        """Check if a user exists."""
1975        return self.get_user(username) is not None
1976    
1977    def save_user(self, user: 'User') -> None:
1978        """Save a user to the database."""
1979        cursor = self.connection.cursor()
1980        cursor.execute(
1981            'INSERT INTO users (username, email, password_hash) VALUES (?, ?, ?)',
1982            (user.username, user.email, user.password_hash)
1983        )
1984        self.connection.commit()
1985"#,
1986        )
1987        .unwrap();
1988
1989        let mut server = crate::CodePrismMcpServer::new().expect("Failed to create server");
1990        server
1991            .initialize_with_repository(repo_path)
1992            .await
1993            .expect("Failed to initialize repository");
1994
1995        // Keep temp_dir alive
1996        std::mem::forget(temp_dir);
1997
1998        server
1999    }
2000
2001    #[tokio::test]
2002    async fn test_prompt_manager_creation() {
2003        let server = create_test_server().await;
2004        let server_arc = std::sync::Arc::new(tokio::sync::RwLock::new(server));
2005        let prompt_manager = PromptManager::new(server_arc);
2006
2007        // Prompt manager should be created successfully
2008    }
2009
2010    #[tokio::test]
2011    async fn test_list_prompts() {
2012        let server = create_test_server().await;
2013        let server_arc = std::sync::Arc::new(tokio::sync::RwLock::new(server));
2014        let prompt_manager = PromptManager::new(server_arc);
2015
2016        let result = prompt_manager
2017            .list_prompts(ListPromptsParams { cursor: None })
2018            .await;
2019        assert!(result.is_ok());
2020
2021        let prompts_result = result.unwrap();
2022        assert_eq!(prompts_result.prompts.len(), 16); // Original 8 + 8 new prompts for large codebase understanding
2023        assert!(prompts_result.next_cursor.is_none());
2024
2025        // Verify all expected prompts are present
2026        let prompt_names: Vec<String> = prompts_result
2027            .prompts
2028            .iter()
2029            .map(|p| p.name.clone())
2030            .collect();
2031        assert!(prompt_names.contains(&"repository_overview".to_string()));
2032        assert!(prompt_names.contains(&"code_analysis".to_string()));
2033        assert!(prompt_names.contains(&"debug_assistance".to_string()));
2034        assert!(prompt_names.contains(&"debug_issue".to_string()));
2035        assert!(prompt_names.contains(&"refactoring_guidance".to_string()));
2036
2037        // Verify prompt structure
2038        for prompt in prompts_result.prompts {
2039            assert!(!prompt.name.is_empty());
2040            assert!(!prompt.description.is_empty());
2041
2042            // Check arguments structure
2043            if let Some(args) = prompt.arguments {
2044                for arg in args {
2045                    assert!(!arg.name.is_empty());
2046                    assert!(!arg.description.is_empty());
2047                }
2048            }
2049        }
2050    }
2051
2052    #[tokio::test]
2053    async fn test_repository_overview_prompt() {
2054        let server = create_test_server().await;
2055        let server_arc = std::sync::Arc::new(tokio::sync::RwLock::new(server));
2056        let prompt_manager = PromptManager::new(server_arc);
2057
2058        let params = GetPromptParams {
2059            name: "repository_overview".to_string(),
2060            arguments: Some(serde_json::Map::from_iter([(
2061                "focus_area".to_string(),
2062                serde_json::Value::String("architecture".to_string()),
2063            )])),
2064        };
2065
2066        let result = prompt_manager.get_prompt(params).await;
2067        assert!(result.is_ok());
2068
2069        let prompt_result = result.unwrap();
2070        assert!(prompt_result.description.is_some());
2071        assert_eq!(prompt_result.messages.len(), 1);
2072
2073        let message = &prompt_result.messages[0];
2074        assert_eq!(message.role, "user");
2075
2076        if let PromptContent::Text { text } = &message.content {
2077            assert!(text.contains("architecture"));
2078            assert!(text.contains("repository"));
2079            assert!(text.contains("analyze"));
2080        } else {
2081            panic!("Expected text content");
2082        }
2083    }
2084
2085    #[tokio::test]
2086    async fn test_repository_overview_prompt_default_focus() {
2087        let server = create_test_server().await;
2088        let server_arc = std::sync::Arc::new(tokio::sync::RwLock::new(server));
2089        let prompt_manager = PromptManager::new(server_arc);
2090
2091        let params = GetPromptParams {
2092            name: "repository_overview".to_string(),
2093            arguments: None, // Test default focus area
2094        };
2095
2096        let result = prompt_manager.get_prompt(params).await;
2097        assert!(result.is_ok());
2098
2099        let prompt_result = result.unwrap();
2100        assert_eq!(prompt_result.messages.len(), 1);
2101
2102        if let PromptContent::Text { text } = &prompt_result.messages[0].content {
2103            assert!(text.contains("general")); // Default focus area
2104        }
2105    }
2106
2107    #[tokio::test]
2108    async fn test_code_analysis_prompt() {
2109        let server = create_test_server().await;
2110        let server_arc = std::sync::Arc::new(tokio::sync::RwLock::new(server));
2111        let prompt_manager = PromptManager::new(server_arc);
2112
2113        let params = GetPromptParams {
2114            name: "code_analysis".to_string(),
2115            arguments: Some(serde_json::Map::from_iter([
2116                (
2117                    "file_pattern".to_string(),
2118                    serde_json::Value::String("*.py".to_string()),
2119                ),
2120                (
2121                    "analysis_type".to_string(),
2122                    serde_json::Value::String("security".to_string()),
2123                ),
2124            ])),
2125        };
2126
2127        let result = prompt_manager.get_prompt(params).await;
2128        assert!(result.is_ok());
2129
2130        let prompt_result = result.unwrap();
2131        assert_eq!(prompt_result.messages.len(), 1);
2132
2133        if let PromptContent::Text { text } = &prompt_result.messages[0].content {
2134            assert!(text.contains("security"));
2135            assert!(text.contains("*.py"));
2136            assert!(text.contains("analysis"));
2137        }
2138    }
2139
2140    #[tokio::test]
2141    async fn test_debug_assistance_prompt() {
2142        let server = create_test_server().await;
2143        let server_arc = std::sync::Arc::new(tokio::sync::RwLock::new(server));
2144        let prompt_manager = PromptManager::new(server_arc);
2145
2146        let params = GetPromptParams {
2147            name: "debug_assistance".to_string(),
2148            arguments: Some(serde_json::Map::from_iter([
2149                (
2150                    "issue_description".to_string(),
2151                    serde_json::Value::String(
2152                        "Authentication is failing for some users".to_string(),
2153                    ),
2154                ),
2155                (
2156                    "affected_files".to_string(),
2157                    serde_json::Value::String("main.py, database.py".to_string()),
2158                ),
2159            ])),
2160        };
2161
2162        let result = prompt_manager.get_prompt(params).await;
2163        assert!(result.is_ok());
2164
2165        let prompt_result = result.unwrap();
2166        assert_eq!(prompt_result.messages.len(), 1);
2167
2168        if let PromptContent::Text { text } = &prompt_result.messages[0].content {
2169            assert!(text.contains("Authentication is failing"));
2170            assert!(text.contains("main.py, database.py"));
2171            assert!(text.contains("debugging"));
2172        }
2173    }
2174
2175    #[tokio::test]
2176    async fn test_debug_assistance_prompt_missing_required_arg() {
2177        let server = create_test_server().await;
2178        let server_arc = std::sync::Arc::new(tokio::sync::RwLock::new(server));
2179        let prompt_manager = PromptManager::new(server_arc);
2180
2181        let params = GetPromptParams {
2182            name: "debug_assistance".to_string(),
2183            arguments: Some(serde_json::Map::from_iter([
2184                (
2185                    "affected_files".to_string(),
2186                    serde_json::Value::String("main.py".to_string()),
2187                ),
2188                // Missing required issue_description
2189            ])),
2190        };
2191
2192        let result = prompt_manager.get_prompt(params).await;
2193        assert!(result.is_err());
2194
2195        let error = result.unwrap_err();
2196        assert!(error.to_string().contains("issue_description"));
2197        assert!(error.to_string().contains("required"));
2198    }
2199
2200    #[tokio::test]
2201    async fn test_debug_issue_prompt() {
2202        let server = create_test_server().await;
2203        let server_arc = std::sync::Arc::new(tokio::sync::RwLock::new(server));
2204        let prompt_manager = PromptManager::new(server_arc);
2205
2206        let params = GetPromptParams {
2207            name: "debug_issue".to_string(),
2208            arguments: Some(serde_json::Map::from_iter([
2209                (
2210                    "error_location".to_string(),
2211                    serde_json::Value::String("main.py:25".to_string()),
2212                ),
2213                (
2214                    "error_message".to_string(),
2215                    serde_json::Value::String(
2216                        "AttributeError: 'NoneType' object has no attribute 'verify_password'"
2217                            .to_string(),
2218                    ),
2219                ),
2220            ])),
2221        };
2222
2223        let result = prompt_manager.get_prompt(params).await;
2224        assert!(result.is_ok());
2225
2226        let prompt_result = result.unwrap();
2227        assert_eq!(prompt_result.messages.len(), 1);
2228
2229        if let PromptContent::Text { text } = &prompt_result.messages[0].content {
2230            assert!(text.contains("main.py:25"));
2231            assert!(text.contains("AttributeError"));
2232            assert!(text.contains("verify_password"));
2233        }
2234    }
2235
2236    #[tokio::test]
2237    async fn test_debug_issue_prompt_missing_required_arg() {
2238        let server = create_test_server().await;
2239        let server_arc = std::sync::Arc::new(tokio::sync::RwLock::new(server));
2240        let prompt_manager = PromptManager::new(server_arc);
2241
2242        let params = GetPromptParams {
2243            name: "debug_issue".to_string(),
2244            arguments: Some(serde_json::Map::from_iter([
2245                (
2246                    "error_message".to_string(),
2247                    serde_json::Value::String("Some error".to_string()),
2248                ),
2249                // Missing required error_location
2250            ])),
2251        };
2252
2253        let result = prompt_manager.get_prompt(params).await;
2254        assert!(result.is_err());
2255
2256        let error = result.unwrap_err();
2257        assert!(error.to_string().contains("error_location"));
2258        assert!(error.to_string().contains("required"));
2259    }
2260
2261    #[tokio::test]
2262    async fn test_refactoring_guidance_prompt() {
2263        let server = create_test_server().await;
2264        let server_arc = std::sync::Arc::new(tokio::sync::RwLock::new(server));
2265        let prompt_manager = PromptManager::new(server_arc);
2266
2267        let params = GetPromptParams {
2268            name: "refactoring_guidance".to_string(),
2269            arguments: Some(serde_json::Map::from_iter([
2270                (
2271                    "target_area".to_string(),
2272                    serde_json::Value::String("UserService class".to_string()),
2273                ),
2274                (
2275                    "refactoring_goal".to_string(),
2276                    serde_json::Value::String("improve testability".to_string()),
2277                ),
2278            ])),
2279        };
2280
2281        let result = prompt_manager.get_prompt(params).await;
2282        assert!(result.is_ok());
2283
2284        let prompt_result = result.unwrap();
2285        assert_eq!(prompt_result.messages.len(), 1);
2286
2287        if let PromptContent::Text { text } = &prompt_result.messages[0].content {
2288            assert!(text.contains("UserService class"));
2289            assert!(text.contains("improve testability"));
2290            assert!(text.contains("refactoring"));
2291        }
2292    }
2293
2294    #[tokio::test]
2295    async fn test_refactoring_guidance_prompt_missing_required_arg() {
2296        let server = create_test_server().await;
2297        let server_arc = std::sync::Arc::new(tokio::sync::RwLock::new(server));
2298        let prompt_manager = PromptManager::new(server_arc);
2299
2300        let params = GetPromptParams {
2301            name: "refactoring_guidance".to_string(),
2302            arguments: Some(serde_json::Map::from_iter([
2303                (
2304                    "refactoring_goal".to_string(),
2305                    serde_json::Value::String("improve performance".to_string()),
2306                ),
2307                // Missing required target_area
2308            ])),
2309        };
2310
2311        let result = prompt_manager.get_prompt(params).await;
2312        assert!(result.is_err());
2313
2314        let error = result.unwrap_err();
2315        assert!(error.to_string().contains("target_area"));
2316        assert!(error.to_string().contains("required"));
2317    }
2318
2319    #[tokio::test]
2320    async fn test_unknown_prompt() {
2321        let server = create_test_server().await;
2322        let server_arc = std::sync::Arc::new(tokio::sync::RwLock::new(server));
2323        let prompt_manager = PromptManager::new(server_arc);
2324
2325        let params = GetPromptParams {
2326            name: "unknown_prompt".to_string(),
2327            arguments: None,
2328        };
2329
2330        let result = prompt_manager.get_prompt(params).await;
2331        assert!(result.is_err());
2332
2333        let error = result.unwrap_err();
2334        assert!(error.to_string().contains("Unknown prompt"));
2335        assert!(error.to_string().contains("unknown_prompt"));
2336    }
2337
2338    #[test]
2339    fn test_prompt_message_serialization() {
2340        let message = PromptMessage {
2341            role: "user".to_string(),
2342            content: PromptContent::Text {
2343                text: "Test message".to_string(),
2344            },
2345        };
2346
2347        let json = serde_json::to_string(&message).unwrap();
2348        let deserialized: PromptMessage = serde_json::from_str(&json).unwrap();
2349
2350        assert_eq!(message.role, deserialized.role);
2351        if let (PromptContent::Text { text: orig }, PromptContent::Text { text: deser }) =
2352            (&message.content, &deserialized.content)
2353        {
2354            assert_eq!(orig, deser);
2355        } else {
2356            panic!("Content type mismatch");
2357        }
2358    }
2359
2360    #[test]
2361    fn test_prompt_content_image() {
2362        let content = PromptContent::Image {
2363            data: "base64encodeddata".to_string(),
2364            mime_type: "image/png".to_string(),
2365        };
2366
2367        let json = serde_json::to_string(&content).unwrap();
2368        let deserialized: PromptContent = serde_json::from_str(&json).unwrap();
2369
2370        if let PromptContent::Image { data, mime_type } = deserialized {
2371            assert_eq!(data, "base64encodeddata");
2372            assert_eq!(mime_type, "image/png");
2373        } else {
2374            panic!("Expected image content");
2375        }
2376    }
2377
2378    #[test]
2379    fn test_get_prompt_params_serialization() {
2380        let mut arguments = serde_json::Map::new();
2381        arguments.insert(
2382            "key".to_string(),
2383            serde_json::Value::String("value".to_string()),
2384        );
2385
2386        let params = GetPromptParams {
2387            name: "test_prompt".to_string(),
2388            arguments: Some(arguments),
2389        };
2390
2391        let json = serde_json::to_string(&params).unwrap();
2392        let deserialized: GetPromptParams = serde_json::from_str(&json).unwrap();
2393
2394        assert_eq!(params.name, deserialized.name);
2395        assert_eq!(params.arguments, deserialized.arguments);
2396    }
2397
2398    #[test]
2399    fn test_get_prompt_result_serialization() {
2400        let result = GetPromptResult {
2401            description: Some("Test prompt result".to_string()),
2402            messages: vec![PromptMessage {
2403                role: "user".to_string(),
2404                content: PromptContent::Text {
2405                    text: "Test content".to_string(),
2406                },
2407            }],
2408        };
2409
2410        let json = serde_json::to_string(&result).unwrap();
2411        let deserialized: GetPromptResult = serde_json::from_str(&json).unwrap();
2412
2413        assert_eq!(result.description, deserialized.description);
2414        assert_eq!(result.messages.len(), deserialized.messages.len());
2415    }
2416
2417    #[test]
2418    fn test_list_prompts_params_serialization() {
2419        let params = ListPromptsParams {
2420            cursor: Some("test_cursor".to_string()),
2421        };
2422
2423        let json = serde_json::to_string(&params).unwrap();
2424        let deserialized: ListPromptsParams = serde_json::from_str(&json).unwrap();
2425
2426        assert_eq!(params.cursor, deserialized.cursor);
2427    }
2428
2429    #[test]
2430    fn test_prompt_argument_serialization() {
2431        let arg = PromptArgument {
2432            name: "test_arg".to_string(),
2433            description: "Test argument".to_string(),
2434            required: true,
2435        };
2436
2437        let json = serde_json::to_value(&arg).unwrap();
2438        assert_eq!(json["name"], "test_arg");
2439        assert_eq!(json["description"], "Test argument");
2440        assert_eq!(json["required"], true);
2441
2442        let deserialized: PromptArgument = serde_json::from_value(json).unwrap();
2443        assert_eq!(deserialized.name, "test_arg");
2444        assert_eq!(deserialized.description, "Test argument");
2445        assert!(deserialized.required);
2446    }
2447
2448    #[tokio::test]
2449    async fn test_architectural_analysis_prompt() {
2450        let server = create_test_server().await;
2451        let prompt_manager =
2452            PromptManager::new(std::sync::Arc::new(tokio::sync::RwLock::new(server)));
2453
2454        let params = GetPromptParams {
2455            name: "architectural_analysis".to_string(),
2456            arguments: Some({
2457                let mut args = serde_json::Map::new();
2458                args.insert("analysis_focus".to_string(), "layers".into());
2459                args.insert("architectural_concerns".to_string(), "coupling".into());
2460                args
2461            }),
2462        };
2463
2464        let result = prompt_manager.get_prompt(params).await;
2465        assert!(result.is_ok());
2466
2467        let prompt_result = result.unwrap();
2468        assert!(prompt_result.description.is_some());
2469        assert_eq!(prompt_result.messages.len(), 1);
2470        assert_eq!(prompt_result.messages[0].role, "user");
2471
2472        if let PromptContent::Text { text } = &prompt_result.messages[0].content {
2473            assert!(text.contains("architectural"));
2474            assert!(text.contains("layers"));
2475        }
2476    }
2477
2478    #[tokio::test]
2479    async fn test_pattern_assessment_prompt() {
2480        let server = create_test_server().await;
2481        let prompt_manager =
2482            PromptManager::new(std::sync::Arc::new(tokio::sync::RwLock::new(server)));
2483
2484        let params = GetPromptParams {
2485            name: "pattern_assessment".to_string(),
2486            arguments: Some({
2487                let mut args = serde_json::Map::new();
2488                args.insert("pattern_types".to_string(), "design_patterns".into());
2489                args.insert("improvement_scope".to_string(), "immediate".into());
2490                args
2491            }),
2492        };
2493
2494        let result = prompt_manager.get_prompt(params).await;
2495        assert!(result.is_ok());
2496
2497        let prompt_result = result.unwrap();
2498        assert_eq!(prompt_result.messages.len(), 1);
2499
2500        if let PromptContent::Text { text } = &prompt_result.messages[0].content {
2501            assert!(text.contains("pattern"));
2502            assert!(text.contains("design_patterns"));
2503        }
2504    }
2505
2506    #[tokio::test]
2507    async fn test_dependency_analysis_prompt() {
2508        let server = create_test_server().await;
2509        let prompt_manager =
2510            PromptManager::new(std::sync::Arc::new(tokio::sync::RwLock::new(server)));
2511
2512        let params = GetPromptParams {
2513            name: "dependency_analysis".to_string(),
2514            arguments: Some({
2515                let mut args = serde_json::Map::new();
2516                args.insert("analysis_target".to_string(), "repository-wide".into());
2517                args.insert("dependency_concerns".to_string(), "cycles".into());
2518                args
2519            }),
2520        };
2521
2522        let result = prompt_manager.get_prompt(params).await;
2523        assert!(result.is_ok());
2524
2525        let prompt_result = result.unwrap();
2526        assert_eq!(prompt_result.messages.len(), 1);
2527
2528        if let PromptContent::Text { text } = &prompt_result.messages[0].content {
2529            assert!(text.contains("dependency"));
2530            assert!(text.contains("cycles"));
2531        }
2532    }
2533
2534    #[tokio::test]
2535    async fn test_new_prompts_in_list() {
2536        let server = create_test_server().await;
2537        let prompt_manager =
2538            PromptManager::new(std::sync::Arc::new(tokio::sync::RwLock::new(server)));
2539
2540        let params = ListPromptsParams { cursor: None };
2541        let result = prompt_manager.list_prompts(params).await;
2542        assert!(result.is_ok());
2543
2544        let prompts_result = result.unwrap();
2545        let prompt_names: Vec<&String> = prompts_result.prompts.iter().map(|p| &p.name).collect();
2546
2547        // Check that our new architectural prompts are included
2548        assert!(prompt_names.contains(&&"architectural_analysis".to_string()));
2549        assert!(prompt_names.contains(&&"pattern_assessment".to_string()));
2550        assert!(prompt_names.contains(&&"dependency_analysis".to_string()));
2551
2552        // Should have all prompts including new ones
2553        assert!(prompts_result.prompts.len() >= 16); // All 16 prompts should be available
2554    }
2555
2556    #[tokio::test]
2557    async fn test_architectural_prompts_with_default_args() {
2558        let server = create_test_server().await;
2559        let prompt_manager =
2560            PromptManager::new(std::sync::Arc::new(tokio::sync::RwLock::new(server)));
2561
2562        // Test architectural_analysis with no arguments (should use defaults)
2563        let params = GetPromptParams {
2564            name: "architectural_analysis".to_string(),
2565            arguments: None,
2566        };
2567
2568        let result = prompt_manager.get_prompt(params).await;
2569        assert!(result.is_ok());
2570
2571        let prompt_result = result.unwrap();
2572        if let PromptContent::Text { text } = &prompt_result.messages[0].content {
2573            assert!(text.contains("general")); // Should use default focus
2574        }
2575    }
2576
2577    #[tokio::test]
2578    async fn test_unknown_architectural_prompt() {
2579        let server = create_test_server().await;
2580        let prompt_manager =
2581            PromptManager::new(std::sync::Arc::new(tokio::sync::RwLock::new(server)));
2582
2583        let params = GetPromptParams {
2584            name: "unknown_architectural_prompt".to_string(),
2585            arguments: None,
2586        };
2587
2588        let result = prompt_manager.get_prompt(params).await;
2589        assert!(result.is_err()); // Should return error for unknown prompt
2590    }
2591}