1use agcodex_ast::Language;
16pub use agcodex_ast::SourceLocation;
17use serde::Deserialize;
18use serde::Serialize;
19use std::collections::HashMap;
20use std::ops::Range;
21use std::path::PathBuf;
22use std::time::Duration;
23use std::time::SystemTime;
24use uuid::Uuid;
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct ComprehensiveToolOutput<T> {
33 pub result: T,
35
36 pub context: OperationContext,
38
39 pub changes: Vec<Change>,
41
42 pub metadata: OperationMetadata,
44
45 pub summary: String,
47
48 pub performance: PerformanceMetrics,
50
51 pub diagnostics: Vec<Diagnostic>,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct OperationContext {
58 pub before: ContextSnapshot,
60
61 pub after: Option<ContextSnapshot>,
63
64 pub surrounding: Vec<ContextLine>,
66
67 pub location: SourceLocation,
69
70 pub scope: OperationScope,
72
73 pub language_context: Option<LanguageContext>,
75
76 pub project_context: Option<ProjectContext>,
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct ContextSnapshot {
83 pub content: String,
85
86 pub timestamp: SystemTime,
88
89 pub content_hash: String,
91
92 pub ast_summary: Option<ComprehensiveAstSummary>,
94
95 pub symbols: Vec<ComprehensiveSymbol>,
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct ContextLine {
102 pub line_number: usize,
104
105 pub content: String,
107
108 pub line_type: ContextLineType,
110
111 pub indentation: usize,
113
114 pub modified: bool,
116}
117
118#[derive(Debug, Clone, Serialize, Deserialize)]
120pub enum ContextLineType {
121 Before,
123 After,
125 Changed,
127 Added,
129 Removed,
131 Separator,
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize)]
137pub struct Change {
138 pub id: Uuid,
140
141 pub kind: ChangeKind,
143
144 pub old: Option<String>,
146
147 pub new: Option<String>,
149
150 pub line_range: Range<usize>,
152
153 pub char_range: Range<usize>,
155
156 pub location: SourceLocation,
158
159 pub semantic_impact: ComprehensiveSemanticImpact,
161
162 pub affected_symbols: Vec<String>,
164
165 pub confidence: f32,
167
168 pub description: String,
170}
171
172#[derive(Debug, Clone, Serialize, Deserialize)]
174pub enum ChangeKind {
175 Added {
177 reason: String,
178 insertion_point: SourceLocation,
179 },
180
181 Modified {
183 why: String,
184 modification_type: ModificationType,
185 },
186
187 Deleted {
189 justification: String,
190 preservation_note: Option<String>,
191 },
192
193 Refactored {
195 from_pattern: String,
196 to_pattern: String,
197 refactor_type: RefactorType,
198 },
199
200 Moved {
202 from: SourceLocation,
203 to: SourceLocation,
204 move_reason: String,
205 },
206
207 Renamed {
209 old_name: String,
210 new_name: String,
211 symbol_type: String,
212 },
213
214 ImportChanged {
216 import_type: ImportChangeType,
217 module_name: String,
218 impact: String,
219 },
220}
221
222#[derive(Debug, Clone, Serialize, Deserialize)]
224pub enum ModificationType {
225 Replacement,
227 ParameterChange,
229 TypeChange,
231 LogicEnhancement,
233 Optimization,
235 BugFix,
237 Formatting,
239}
240
241#[derive(Debug, Clone, Serialize, Deserialize)]
243pub enum RefactorType {
244 ExtractMethod,
246 InlineMethod,
248 MoveMethod,
250 RenameSymbol,
252 ExtractVariable,
254 ExtractConstant,
256 ChangeSignature,
258 LambdaConversion,
260}
261
262#[derive(Debug, Clone, Serialize, Deserialize)]
264pub enum ImportChangeType {
265 Added,
266 Removed,
267 Modified,
268 Reorganized,
269}
270
271#[derive(Debug, Clone, Serialize, Deserialize)]
273pub struct ComprehensiveSemanticImpact {
274 pub level: ImpactLevel,
276
277 pub scope: ImpactScope,
279
280 pub breaking_changes: Vec<BreakingChange>,
282
283 pub api_compatibility: ApiCompatibility,
285
286 pub performance_impact: ComprehensivePerformanceImpact,
288
289 pub security_impact: SecurityImpact,
291
292 pub test_impact: TestImpact,
294}
295
296#[derive(Debug, Clone, Serialize, Deserialize)]
298pub enum ImpactLevel {
299 None,
301 Local,
303 Interface,
305 Architectural,
307 Critical,
309}
310
311#[derive(Debug, Clone, Serialize, Deserialize)]
313pub enum ImpactScope {
314 Statement,
316 Function,
318 Class,
320 Module,
322 Package,
324 Project,
326 Dependencies,
328}
329
330#[derive(Debug, Clone, Serialize, Deserialize)]
332pub struct BreakingChange {
333 pub description: String,
335
336 pub affected_apis: Vec<String>,
338
339 pub migration_strategy: Option<String>,
341
342 pub severity: BreakingSeverity,
344}
345
346#[derive(Debug, Clone, Serialize, Deserialize)]
348pub enum BreakingSeverity {
349 Minor,
351 Major,
353 Critical,
355}
356
357#[derive(Debug, Clone, Serialize, Deserialize)]
359pub struct ApiCompatibility {
360 pub backward_compatible: bool,
362
363 pub version_impact: VersionImpact,
365
366 pub deprecated_usage: Vec<String>,
368
369 pub new_features: Vec<String>,
371}
372
373#[derive(Debug, Clone, Serialize, Deserialize)]
375pub enum VersionImpact {
376 Patch,
378 Minor,
380 Major,
382}
383
384#[derive(Debug, Clone, Serialize, Deserialize)]
386pub struct ComprehensivePerformanceImpact {
387 pub expected_change: PerformanceChange,
389
390 pub complexity_change: Option<ComplexityChange>,
392
393 pub memory_impact: MemoryImpact,
395
396 pub cpu_impact: String,
398
399 pub io_impact: String,
401}
402
403#[derive(Debug, Clone, Serialize, Deserialize)]
405pub enum PerformanceChange {
406 Improvement(String),
408 Neutral,
410 Degradation(String),
412 Unknown,
414}
415
416#[derive(Debug, Clone, Serialize, Deserialize)]
418pub struct ComplexityChange {
419 pub time_complexity: (String, String),
421
422 pub space_complexity: (String, String),
424
425 pub cyclomatic_complexity_delta: i32,
427}
428
429#[derive(Debug, Clone, Serialize, Deserialize)]
431pub struct MemoryImpact {
432 pub estimated_bytes_delta: Option<i64>,
434
435 pub allocation_changes: Vec<String>,
437
438 pub leak_risks: Vec<String>,
440}
441
442#[derive(Debug, Clone, Serialize, Deserialize)]
444pub struct SecurityImpact {
445 pub level: SecurityLevel,
447
448 pub vulnerabilities: Vec<SecurityVulnerability>,
450
451 pub improvements: Vec<String>,
453
454 pub requires_review: bool,
456}
457
458#[derive(Debug, Clone, Serialize, Deserialize)]
460pub enum SecurityLevel {
461 None,
463 Low,
465 Medium,
467 High,
469 Critical,
471}
472
473#[derive(Debug, Clone, Serialize, Deserialize)]
475pub struct SecurityVulnerability {
476 pub vulnerability_type: String,
478
479 pub description: String,
481
482 pub severity: SecurityLevel,
484
485 pub mitigation: Vec<String>,
487}
488
489#[derive(Debug, Clone, Serialize, Deserialize)]
491pub struct TestImpact {
492 pub affected_tests: Vec<String>,
494
495 pub required_tests: Vec<String>,
497
498 pub coverage_impact: CoverageImpact,
500
501 pub test_categories: Vec<TestCategory>,
503}
504
505#[derive(Debug, Clone, Serialize, Deserialize)]
507pub struct CoverageImpact {
508 pub coverage_delta: Option<f32>,
510
511 pub uncovered_lines: Vec<usize>,
513
514 pub recommendations: Vec<String>,
516}
517
518#[derive(Debug, Clone, Serialize, Deserialize)]
520pub enum TestCategory {
521 Unit,
522 Integration,
523 EndToEnd,
524 Performance,
525 Security,
526 Regression,
527}
528
529#[derive(Debug, Clone, Serialize, Deserialize)]
531pub struct OperationScope {
532 pub scope_type: ScopeType,
534
535 pub name: String,
537
538 pub path: Vec<String>,
540
541 pub file_path: PathBuf,
543
544 pub line_range: Range<usize>,
546}
547
548#[derive(Debug, Clone, Serialize, Deserialize)]
550pub enum ScopeType {
551 Global,
553 File,
555 Namespace,
557 Class,
559 Function,
561 Block,
563 Expression,
565}
566
567#[derive(Debug, Clone, Serialize, Deserialize)]
569pub struct LanguageContext {
570 pub language: Language,
572
573 pub version: Option<String>,
575
576 pub features: Vec<String>,
578
579 pub frameworks: Vec<String>,
581
582 pub runtime_context: Vec<String>,
584}
585
586#[derive(Debug, Clone, Serialize, Deserialize)]
588pub struct ProjectContext {
589 pub name: Option<String>,
591
592 pub project_type: Option<String>,
594
595 pub build_system: Option<String>,
597
598 pub dependencies: Vec<DependencyInfo>,
600
601 pub config_files: Vec<PathBuf>,
603}
604
605#[derive(Debug, Clone, Serialize, Deserialize)]
607pub struct DependencyInfo {
608 pub name: String,
610
611 pub version: Option<String>,
613
614 pub dependency_type: String,
616
617 pub change_type: String,
619}
620
621#[derive(Debug, Clone, Serialize, Deserialize)]
623pub struct OperationMetadata {
624 pub tool: String,
626
627 pub operation: String,
629
630 pub operation_id: Uuid,
632
633 pub started_at: SystemTime,
635
636 pub completed_at: SystemTime,
638
639 pub confidence: f32,
641
642 pub parameters: HashMap<String, String>,
644
645 pub tool_version: String,
647
648 pub initiated_by: Option<String>,
650
651 pub session_id: Option<Uuid>,
653}
654
655#[derive(Debug, Clone, Serialize, Deserialize)]
657pub struct PerformanceMetrics {
658 pub execution_time: Duration,
660
661 pub phase_times: HashMap<String, Duration>,
663
664 pub memory_usage: MemoryUsage,
666
667 pub cpu_usage: CpuUsage,
669
670 pub io_stats: IoStats,
672
673 pub cache_stats: CacheStats,
675}
676
677#[derive(Debug, Clone, Serialize, Deserialize)]
679pub struct MemoryUsage {
680 pub peak_bytes: u64,
682
683 pub average_bytes: u64,
685
686 pub allocations: u64,
688
689 pub deallocations: u64,
691
692 pub efficiency_score: f32,
694}
695
696#[derive(Debug, Clone, Serialize, Deserialize)]
698pub struct CpuUsage {
699 pub cpu_time: Duration,
701
702 pub utilization_percent: f32,
704
705 pub context_switches: u64,
707}
708
709#[derive(Debug, Clone, Serialize, Deserialize)]
711pub struct IoStats {
712 pub bytes_read: u64,
714
715 pub bytes_written: u64,
717
718 pub read_ops: u64,
720
721 pub write_ops: u64,
723
724 pub io_wait_time: Duration,
726}
727
728#[derive(Debug, Clone, Serialize, Deserialize)]
730pub struct CacheStats {
731 pub hit_rate: f32,
733
734 pub hits: u64,
736
737 pub misses: u64,
739
740 pub cache_size: u64,
742
743 pub efficiency_score: f32,
745}
746
747#[derive(Debug, Clone, Serialize, Deserialize)]
749pub struct Diagnostic {
750 pub level: DiagnosticLevel,
752
753 pub message: String,
755
756 pub location: Option<SourceLocation>,
758
759 pub _code: Option<String>,
761
762 pub suggestions: Vec<String>,
764
765 pub related: Vec<Uuid>,
767}
768
769#[derive(Debug, Clone, Serialize, Deserialize)]
771pub enum DiagnosticLevel {
772 Info,
774 Warning,
776 Error,
778 Hint,
780}
781
782#[derive(Debug, Clone, Serialize, Deserialize)]
784pub struct ComprehensiveAstSummary {
785 pub root_type: String,
787
788 pub node_count: usize,
790
791 pub max_depth: usize,
793
794 pub symbols: Vec<ComprehensiveSymbol>,
796
797 pub complexity: ComplexityMetrics,
799
800 pub ast_hash: String,
802}
803
804#[derive(Debug, Clone, Serialize, Deserialize)]
806pub struct ComprehensiveSymbol {
807 pub name: String,
809
810 pub symbol_type: SymbolType,
812
813 pub location: SourceLocation,
815
816 pub visibility: Visibility,
818
819 pub signature: Option<String>,
821
822 pub documentation: Option<String>,
824}
825
826#[derive(Debug, Clone, Serialize, Deserialize)]
828pub enum SymbolType {
829 Function,
830 Method,
831 Class,
832 Struct,
833 Interface,
834 Trait,
835 Variable,
836 Constant,
837 Type,
838 Macro,
839 Module,
840 Namespace,
841}
842
843#[derive(Debug, Clone, Serialize, Deserialize)]
845pub enum Visibility {
846 Public,
847 Private,
848 Protected,
849 Internal,
850 PackagePrivate,
851}
852
853#[derive(Debug, Clone, Serialize, Deserialize)]
855pub struct ComplexityMetrics {
856 pub cyclomatic: u32,
858
859 pub cognitive: u32,
861
862 pub halstead: Option<HalsteadMetrics>,
864
865 pub lines_of_code: u32,
867
868 pub function_count: u32,
870
871 pub max_nesting_depth: u32,
873}
874
875#[derive(Debug, Clone, Serialize, Deserialize)]
877pub struct HalsteadMetrics {
878 pub distinct_operators: u32,
880
881 pub distinct_operands: u32,
883
884 pub total_operators: u32,
886
887 pub total_operands: u32,
889
890 pub vocabulary: u32,
892
893 pub length: u32,
895
896 pub volume: f64,
898
899 pub difficulty: f64,
901
902 pub effort: f64,
904}
905
906pub trait ResultExt<T, E> {
910 fn to_tool_output(
912 self,
913 tool: &'static str,
914 operation: String,
915 location: SourceLocation,
916 ) -> ComprehensiveToolOutput<Option<T>>
917 where
918 E: std::fmt::Display;
919}
920
921impl<T, E> ResultExt<T, E> for Result<T, E> {
922 fn to_tool_output(
923 self,
924 tool: &'static str,
925 operation: String,
926 location: SourceLocation,
927 ) -> ComprehensiveToolOutput<Option<T>>
928 where
929 E: std::fmt::Display,
930 {
931 match self {
932 Ok(value) => OutputBuilder::new(Some(value), tool, operation, location).build(),
933 Err(error) => OutputBuilder::new(None, tool, operation, location)
934 .error(error.to_string())
935 .confidence(0.0)
936 .build(),
937 }
938 }
939}
940
941impl<T> ComprehensiveToolOutput<T> {
943 pub fn new(result: T, tool: &str, operation: String, location: SourceLocation) -> Self {
945 let operation_id = Uuid::new_v4();
946 let now = SystemTime::now();
947
948 Self {
949 result,
950 context: OperationContext::minimal(location),
951 changes: Vec::new(),
952 metadata: OperationMetadata {
953 tool: tool.to_string(),
954 operation,
955 operation_id,
956 started_at: now,
957 completed_at: now,
958 confidence: 1.0,
959 parameters: HashMap::new(),
960 tool_version: "0.1.0".to_string(),
961 initiated_by: None,
962 session_id: None,
963 },
964 summary: "Operation completed successfully".to_string(),
965 performance: PerformanceMetrics::default(),
966 diagnostics: Vec::new(),
967 }
968 }
969
970 pub fn add_change(mut self, change: Change) -> Self {
972 self.changes.push(change);
973 self
974 }
975
976 pub fn add_changes(mut self, changes: Vec<Change>) -> Self {
978 self.changes.extend(changes);
979 self
980 }
981
982 pub fn add_diagnostic(mut self, diagnostic: Diagnostic) -> Self {
984 self.diagnostics.push(diagnostic);
985 self
986 }
987
988 pub fn with_summary(mut self, summary: String) -> Self {
990 self.summary = summary;
991 self
992 }
993
994 pub const fn with_confidence(mut self, confidence: f32) -> Self {
996 self.metadata.confidence = confidence.clamp(0.0, 1.0);
997 self
998 }
999
1000 pub fn has_errors(&self) -> bool {
1002 self.diagnostics
1003 .iter()
1004 .any(|d| matches!(d.level, DiagnosticLevel::Error))
1005 }
1006
1007 pub fn has_warnings(&self) -> bool {
1009 self.diagnostics
1010 .iter()
1011 .any(|d| matches!(d.level, DiagnosticLevel::Warning))
1012 }
1013
1014 pub fn max_impact_level(&self) -> ImpactLevel {
1016 self.changes
1017 .iter()
1018 .map(|c| &c.semantic_impact.level)
1019 .max_by_key(|level| match level {
1020 ImpactLevel::None => 0,
1021 ImpactLevel::Local => 1,
1022 ImpactLevel::Interface => 2,
1023 ImpactLevel::Architectural => 3,
1024 ImpactLevel::Critical => 4,
1025 })
1026 .cloned()
1027 .unwrap_or(ImpactLevel::None)
1028 }
1029}
1030
1031impl OperationContext {
1032 pub fn minimal(location: SourceLocation) -> Self {
1034 Self {
1035 before: ContextSnapshot::empty(),
1036 after: None,
1037 surrounding: Vec::new(),
1038 location,
1039 scope: OperationScope::minimal(),
1040 language_context: None,
1041 project_context: None,
1042 }
1043 }
1044}
1045
1046impl ContextSnapshot {
1047 pub fn empty() -> Self {
1049 Self {
1050 content: String::new(),
1051 timestamp: SystemTime::now(),
1052 content_hash: "empty".to_string(),
1053 ast_summary: None,
1054 symbols: Vec::new(),
1055 }
1056 }
1057}
1058
1059impl OperationScope {
1060 pub fn minimal() -> Self {
1062 Self {
1063 scope_type: ScopeType::Global,
1064 name: "global".to_string(),
1065 path: vec!["global".to_string()],
1066 file_path: PathBuf::new(),
1067 line_range: 0..0,
1068 }
1069 }
1070}
1071
1072impl Default for PerformanceMetrics {
1073 fn default() -> Self {
1074 Self {
1075 execution_time: Duration::from_millis(0),
1076 phase_times: HashMap::new(),
1077 memory_usage: MemoryUsage::default(),
1078 cpu_usage: CpuUsage::default(),
1079 io_stats: IoStats::default(),
1080 cache_stats: CacheStats::default(),
1081 }
1082 }
1083}
1084
1085impl Default for MemoryUsage {
1086 fn default() -> Self {
1087 Self {
1088 peak_bytes: 0,
1089 average_bytes: 0,
1090 allocations: 0,
1091 deallocations: 0,
1092 efficiency_score: 1.0,
1093 }
1094 }
1095}
1096
1097impl Default for CpuUsage {
1098 fn default() -> Self {
1099 Self {
1100 cpu_time: Duration::from_millis(0),
1101 utilization_percent: 0.0,
1102 context_switches: 0,
1103 }
1104 }
1105}
1106
1107impl Default for IoStats {
1108 fn default() -> Self {
1109 Self {
1110 bytes_read: 0,
1111 bytes_written: 0,
1112 read_ops: 0,
1113 write_ops: 0,
1114 io_wait_time: Duration::from_millis(0),
1115 }
1116 }
1117}
1118
1119impl Default for CacheStats {
1120 fn default() -> Self {
1121 Self {
1122 hit_rate: 0.0,
1123 hits: 0,
1124 misses: 0,
1125 cache_size: 0,
1126 efficiency_score: 0.0,
1127 }
1128 }
1129}
1130
1131impl Change {
1132 pub fn addition(location: SourceLocation, content: String, reason: String) -> Self {
1134 Self {
1135 id: Uuid::new_v4(),
1136 kind: ChangeKind::Added {
1137 reason,
1138 insertion_point: location.clone(),
1139 },
1140 old: None,
1141 new: Some(content),
1142 line_range: location.start_line..location.start_line + 1,
1143 char_range: location.start_column..location.start_column + 1,
1144 location,
1145 semantic_impact: ComprehensiveSemanticImpact::minimal(),
1146 affected_symbols: Vec::new(),
1147 confidence: 1.0,
1148 description: "Content added".to_string(),
1149 }
1150 }
1151
1152 pub fn modification(
1154 location: SourceLocation,
1155 old_content: String,
1156 new_content: String,
1157 why: String,
1158 ) -> Self {
1159 Self {
1160 id: Uuid::new_v4(),
1161 kind: ChangeKind::Modified {
1162 why,
1163 modification_type: ModificationType::Replacement,
1164 },
1165 old: Some(old_content),
1166 new: Some(new_content),
1167 line_range: location.start_line..location.start_line + 1,
1168 char_range: location.start_column..location.start_column + 1,
1169 location,
1170 semantic_impact: ComprehensiveSemanticImpact::minimal(),
1171 affected_symbols: Vec::new(),
1172 confidence: 1.0,
1173 description: "Content modified".to_string(),
1174 }
1175 }
1176
1177 pub fn deletion(location: SourceLocation, content: String, justification: String) -> Self {
1179 Self {
1180 id: Uuid::new_v4(),
1181 kind: ChangeKind::Deleted {
1182 justification,
1183 preservation_note: None,
1184 },
1185 old: Some(content),
1186 new: None,
1187 line_range: location.start_line..location.start_line + 1,
1188 char_range: location.start_column..location.start_column + 1,
1189 location,
1190 semantic_impact: ComprehensiveSemanticImpact::minimal(),
1191 affected_symbols: Vec::new(),
1192 confidence: 1.0,
1193 description: "Content deleted".to_string(),
1194 }
1195 }
1196}
1197
1198impl ComprehensiveSemanticImpact {
1199 pub fn minimal() -> Self {
1201 Self {
1202 level: ImpactLevel::Local,
1203 scope: ImpactScope::Statement,
1204 breaking_changes: Vec::new(),
1205 api_compatibility: ApiCompatibility::compatible(),
1206 performance_impact: ComprehensivePerformanceImpact::neutral(),
1207 security_impact: SecurityImpact::none(),
1208 test_impact: TestImpact::minimal(),
1209 }
1210 }
1211}
1212
1213impl ApiCompatibility {
1214 pub const fn compatible() -> Self {
1216 Self {
1217 backward_compatible: true,
1218 version_impact: VersionImpact::Patch,
1219 deprecated_usage: Vec::new(),
1220 new_features: Vec::new(),
1221 }
1222 }
1223}
1224
1225impl ComprehensivePerformanceImpact {
1226 pub fn neutral() -> Self {
1228 Self {
1229 expected_change: PerformanceChange::Neutral,
1230 complexity_change: None,
1231 memory_impact: MemoryImpact::neutral(),
1232 cpu_impact: "No significant impact".to_string(),
1233 io_impact: "No significant impact".to_string(),
1234 }
1235 }
1236}
1237
1238impl MemoryImpact {
1239 pub const fn neutral() -> Self {
1241 Self {
1242 estimated_bytes_delta: None,
1243 allocation_changes: Vec::new(),
1244 leak_risks: Vec::new(),
1245 }
1246 }
1247}
1248
1249impl SecurityImpact {
1250 pub const fn none() -> Self {
1252 Self {
1253 level: SecurityLevel::None,
1254 vulnerabilities: Vec::new(),
1255 improvements: Vec::new(),
1256 requires_review: false,
1257 }
1258 }
1259}
1260
1261impl TestImpact {
1262 pub const fn minimal() -> Self {
1264 Self {
1265 affected_tests: Vec::new(),
1266 required_tests: Vec::new(),
1267 coverage_impact: CoverageImpact::neutral(),
1268 test_categories: Vec::new(),
1269 }
1270 }
1271}
1272
1273impl CoverageImpact {
1274 pub const fn neutral() -> Self {
1276 Self {
1277 coverage_delta: None,
1278 uncovered_lines: Vec::new(),
1279 recommendations: Vec::new(),
1280 }
1281 }
1282}
1283
1284impl Diagnostic {
1285 pub const fn info(message: String) -> Self {
1287 Self {
1288 level: DiagnosticLevel::Info,
1289 message,
1290 location: None,
1291 _code: None,
1292 suggestions: Vec::new(),
1293 related: Vec::new(),
1294 }
1295 }
1296
1297 pub const fn warning(message: String) -> Self {
1299 Self {
1300 level: DiagnosticLevel::Warning,
1301 message,
1302 location: None,
1303 _code: None,
1304 suggestions: Vec::new(),
1305 related: Vec::new(),
1306 }
1307 }
1308
1309 pub const fn error(message: String) -> Self {
1311 Self {
1312 level: DiagnosticLevel::Error,
1313 message,
1314 location: None,
1315 _code: None,
1316 suggestions: Vec::new(),
1317 related: Vec::new(),
1318 }
1319 }
1320
1321 pub fn with_suggestion(mut self, suggestion: String) -> Self {
1323 self.suggestions.push(suggestion);
1324 self
1325 }
1326
1327 pub fn at_location(mut self, location: SourceLocation) -> Self {
1329 self.location = Some(location);
1330 self
1331 }
1332
1333 pub fn with_code(mut self, code: String) -> Self {
1335 self._code = Some(code);
1336 self
1337 }
1338}
1339
1340pub struct OutputBuilder<T> {
1344 result: T,
1345 tool: String,
1346 operation: String,
1347 location: SourceLocation,
1348 changes: Vec<Change>,
1349 diagnostics: Vec<Diagnostic>,
1350 confidence: f32,
1351 summary: Option<String>,
1352 context: Option<OperationContext>,
1353 performance: Option<PerformanceMetrics>,
1354}
1355
1356impl<T> OutputBuilder<T> {
1357 pub fn new(result: T, tool: &str, operation: String, location: SourceLocation) -> Self {
1359 Self {
1360 result,
1361 tool: tool.to_string(),
1362 operation,
1363 location,
1364 changes: Vec::new(),
1365 diagnostics: Vec::new(),
1366 confidence: 1.0,
1367 summary: None,
1368 context: None,
1369 performance: None,
1370 }
1371 }
1372
1373 pub fn change(mut self, change: Change) -> Self {
1375 self.changes.push(change);
1376 self
1377 }
1378
1379 pub fn changes(mut self, changes: Vec<Change>) -> Self {
1381 self.changes.extend(changes);
1382 self
1383 }
1384
1385 pub fn diagnostic(mut self, diagnostic: Diagnostic) -> Self {
1387 self.diagnostics.push(diagnostic);
1388 self
1389 }
1390
1391 pub fn info(mut self, message: String) -> Self {
1393 self.diagnostics.push(Diagnostic::info(message));
1394 self
1395 }
1396
1397 pub fn warning(mut self, message: String) -> Self {
1399 self.diagnostics.push(Diagnostic::warning(message));
1400 self
1401 }
1402
1403 pub fn error(mut self, message: String) -> Self {
1405 self.diagnostics.push(Diagnostic::error(message));
1406 self
1407 }
1408
1409 pub const fn confidence(mut self, confidence: f32) -> Self {
1411 self.confidence = confidence.clamp(0.0, 1.0);
1412 self
1413 }
1414
1415 pub fn summary(mut self, summary: String) -> Self {
1417 self.summary = Some(summary);
1418 self
1419 }
1420
1421 pub fn context(mut self, context: OperationContext) -> Self {
1423 self.context = Some(context);
1424 self
1425 }
1426
1427 pub fn performance(mut self, performance: PerformanceMetrics) -> Self {
1429 self.performance = Some(performance);
1430 self
1431 }
1432
1433 pub fn build(self) -> ComprehensiveToolOutput<T> {
1435 let operation_id = Uuid::new_v4();
1436 let now = SystemTime::now();
1437
1438 let summary = self.summary.unwrap_or_else(|| {
1439 if self
1440 .diagnostics
1441 .iter()
1442 .any(|d| matches!(d.level, DiagnosticLevel::Error))
1443 {
1444 "Operation completed with errors".to_string()
1445 } else if self
1446 .diagnostics
1447 .iter()
1448 .any(|d| matches!(d.level, DiagnosticLevel::Warning))
1449 {
1450 "Operation completed with warnings".to_string()
1451 } else {
1452 "Operation completed successfully".to_string()
1453 }
1454 });
1455
1456 ComprehensiveToolOutput {
1457 result: self.result,
1458 context: self
1459 .context
1460 .unwrap_or_else(|| OperationContext::minimal(self.location.clone())),
1461 changes: self.changes,
1462 metadata: OperationMetadata {
1463 tool: self.tool,
1464 operation: self.operation,
1465 operation_id,
1466 started_at: now,
1467 completed_at: now,
1468 confidence: self.confidence,
1469 parameters: HashMap::new(),
1470 tool_version: "0.1.0".to_string(),
1471 initiated_by: None,
1472 session_id: None,
1473 },
1474 summary,
1475 performance: self.performance.unwrap_or_default(),
1476 diagnostics: self.diagnostics,
1477 }
1478 }
1479}
1480
1481pub struct ChangeBuilder {
1483 location: SourceLocation,
1484 old: Option<String>,
1485 new: Option<String>,
1486 description: Option<String>,
1487 confidence: f32,
1488 affected_symbols: Vec<String>,
1489 impact: Option<ComprehensiveSemanticImpact>,
1490}
1491
1492impl ChangeBuilder {
1493 pub const fn new(location: SourceLocation) -> Self {
1495 Self {
1496 location,
1497 old: None,
1498 new: None,
1499 description: None,
1500 confidence: 1.0,
1501 affected_symbols: Vec::new(),
1502 impact: None,
1503 }
1504 }
1505
1506 pub fn old_content(mut self, content: String) -> Self {
1508 self.old = Some(content);
1509 self
1510 }
1511
1512 pub fn new_content(mut self, content: String) -> Self {
1514 self.new = Some(content);
1515 self
1516 }
1517
1518 pub fn description(mut self, description: String) -> Self {
1520 self.description = Some(description);
1521 self
1522 }
1523
1524 pub const fn confidence(mut self, confidence: f32) -> Self {
1526 self.confidence = confidence.clamp(0.0, 1.0);
1527 self
1528 }
1529
1530 pub fn symbol(mut self, symbol: String) -> Self {
1532 self.affected_symbols.push(symbol);
1533 self
1534 }
1535
1536 pub fn impact(mut self, impact: ComprehensiveSemanticImpact) -> Self {
1538 self.impact = Some(impact);
1539 self
1540 }
1541
1542 pub fn addition(self, reason: String) -> Change {
1544 let description = self
1545 .description
1546 .unwrap_or_else(|| "Content added".to_string());
1547 Change {
1548 id: Uuid::new_v4(),
1549 kind: ChangeKind::Added {
1550 reason,
1551 insertion_point: self.location.clone(),
1552 },
1553 old: self.old,
1554 new: self.new,
1555 line_range: self.location.start_line..self.location.start_line + 1,
1556 char_range: self.location.start_column..self.location.start_column + 1,
1557 location: self.location,
1558 semantic_impact: self
1559 .impact
1560 .unwrap_or_else(ComprehensiveSemanticImpact::minimal),
1561 affected_symbols: self.affected_symbols,
1562 confidence: self.confidence,
1563 description,
1564 }
1565 }
1566
1567 pub fn modification(self, why: String, modification_type: ModificationType) -> Change {
1569 let description = self
1570 .description
1571 .unwrap_or_else(|| "Content modified".to_string());
1572 Change {
1573 id: Uuid::new_v4(),
1574 kind: ChangeKind::Modified {
1575 why,
1576 modification_type,
1577 },
1578 old: self.old,
1579 new: self.new,
1580 line_range: self.location.start_line..self.location.start_line + 1,
1581 char_range: self.location.start_column..self.location.start_column + 1,
1582 location: self.location,
1583 semantic_impact: self
1584 .impact
1585 .unwrap_or_else(ComprehensiveSemanticImpact::minimal),
1586 affected_symbols: self.affected_symbols,
1587 confidence: self.confidence,
1588 description,
1589 }
1590 }
1591
1592 pub fn deletion(self, justification: String) -> Change {
1594 let description = self
1595 .description
1596 .unwrap_or_else(|| "Content deleted".to_string());
1597 Change {
1598 id: Uuid::new_v4(),
1599 kind: ChangeKind::Deleted {
1600 justification,
1601 preservation_note: None,
1602 },
1603 old: self.old,
1604 new: self.new,
1605 line_range: self.location.start_line..self.location.start_line + 1,
1606 char_range: self.location.start_column..self.location.start_column + 1,
1607 location: self.location,
1608 semantic_impact: self
1609 .impact
1610 .unwrap_or_else(ComprehensiveSemanticImpact::minimal),
1611 affected_symbols: self.affected_symbols,
1612 confidence: self.confidence,
1613 description,
1614 }
1615 }
1616}
1617
1618pub fn simple_success<T>(
1622 result: T,
1623 tool: &'static str,
1624 operation: String,
1625 summary: String,
1626) -> ComprehensiveToolOutput<T> {
1627 let location = SourceLocation::new("unknown", 0, 0, 0, 0, (0, 0));
1628 OutputBuilder::new(result, tool, operation, location)
1629 .summary(summary)
1630 .build()
1631}
1632
1633pub fn simple_error<T>(
1635 result: T,
1636 tool: &'static str,
1637 operation: String,
1638 error_message: String,
1639) -> ComprehensiveToolOutput<T> {
1640 let location = SourceLocation::new("unknown", 0, 0, 0, 0, (0, 0));
1641 OutputBuilder::new(result, tool, operation, location)
1642 .error(error_message)
1643 .confidence(0.0)
1644 .build()
1645}
1646
1647pub fn single_file_modification<T>(
1649 result: T,
1650 tool: &'static str,
1651 operation: String,
1652 file_path: &str,
1653 line: usize,
1654 column: usize,
1655 old_content: String,
1656 new_content: String,
1657 reason: String,
1658) -> ComprehensiveToolOutput<T> {
1659 let location = SourceLocation::new(file_path, line, column, line, column, (0, 0));
1660 let change = ChangeBuilder::new(location.clone())
1661 .old_content(old_content)
1662 .new_content(new_content)
1663 .modification(reason.clone(), ModificationType::Replacement);
1664
1665 OutputBuilder::new(result, tool, operation, location)
1666 .change(change)
1667 .summary(format!(
1668 "Modified {} at line {}: {}",
1669 file_path, line, reason
1670 ))
1671 .build()
1672}
1673
1674pub fn multi_file_changes<T>(
1676 result: T,
1677 tool: &'static str,
1678 operation: String,
1679 changes: Vec<Change>,
1680) -> ComprehensiveToolOutput<T> {
1681 let location = if let Some(first_change) = changes.first() {
1682 first_change.location.clone()
1683 } else {
1684 SourceLocation::new("unknown", 0, 0, 0, 0, (0, 0))
1685 };
1686
1687 let summary = if changes.is_empty() {
1688 "No changes made".to_string()
1689 } else {
1690 format!("Made {} changes across files", changes.len())
1691 };
1692
1693 OutputBuilder::new(result, tool, operation, location)
1694 .changes(changes)
1695 .summary(summary)
1696 .build()
1697}
1698
1699pub struct PerformanceTimer {
1701 started_at: SystemTime,
1702 phase_times: HashMap<String, Duration>,
1703 current_phase: Option<String>,
1704 current_phase_start: Option<SystemTime>,
1705}
1706
1707impl PerformanceTimer {
1708 pub fn new() -> Self {
1710 Self {
1711 started_at: SystemTime::now(),
1712 phase_times: HashMap::new(),
1713 current_phase: None,
1714 current_phase_start: None,
1715 }
1716 }
1717
1718 pub fn start_phase(&mut self, phase_name: String) {
1720 self.current_phase = Some(phase_name);
1722 self.current_phase_start = Some(SystemTime::now());
1723 }
1724
1725 pub fn end_current_phase(&mut self) {
1727 if let (Some(phase_name), Some(start_time)) =
1728 (self.current_phase.take(), self.current_phase_start.take())
1729 && let Ok(duration) = start_time.elapsed()
1730 {
1731 self.phase_times.insert(phase_name, duration);
1732 }
1733 }
1734
1735 pub fn elapsed(&self) -> Duration {
1737 self.started_at.elapsed().unwrap_or_default()
1738 }
1739
1740 pub fn metrics(mut self) -> PerformanceMetrics {
1742 self.end_current_phase();
1743
1744 let execution_time = self.started_at.elapsed().unwrap_or_default();
1745
1746 PerformanceMetrics {
1747 execution_time,
1748 phase_times: self.phase_times,
1749 memory_usage: MemoryUsage::default(),
1750 cpu_usage: CpuUsage::default(),
1751 io_stats: IoStats::default(),
1752 cache_stats: CacheStats::default(),
1753 }
1754 }
1755}
1756
1757impl Default for PerformanceTimer {
1758 fn default() -> Self {
1759 Self::new()
1760 }
1761}