agcodex_core/tools/
output.rs

1//! Context-aware output structures for AGCodex tools
2//!
3//! This module provides unified, rich output structures that give agents and LLMs
4//! comprehensive context about tool operations. All tools should use these common
5//! structures to ensure consistent, analyzable results.
6//!
7//! ## Design Principles
8//! - **Context-first**: Every operation includes before/after context
9//! - **Location-aware**: Precise file:line:column information for all changes
10//! - **Semantic understanding**: Impact analysis beyond text-level changes
11//! - **LLM-optimized**: Structured data with human-readable summaries
12//! - **Serializable**: Full serde support for persistence and transmission
13
14// use agcodex_ast::AstNode; // unused
15use 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/// Primary comprehensive output structure for all AGCodex tools
27///
28/// This provides a unified, context-rich structure that enhances
29/// the simpler tool-specific output implementations with comprehensive
30/// information about tool operations.
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct ComprehensiveToolOutput<T> {
33    /// The primary result of the tool operation
34    pub result: T,
35
36    /// Rich contextual information about the operation
37    pub context: OperationContext,
38
39    /// All changes made during the operation
40    pub changes: Vec<Change>,
41
42    /// Comprehensive metadata about the operation
43    pub metadata: OperationMetadata,
44
45    /// Human-readable summary optimized for LLM consumption
46    pub summary: String,
47
48    /// Performance and execution metrics
49    pub performance: PerformanceMetrics,
50
51    /// Warnings, errors, or other diagnostic information
52    pub diagnostics: Vec<Diagnostic>,
53}
54
55/// Rich contextual information about a tool operation
56#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct OperationContext {
58    /// State before the operation
59    pub before: ContextSnapshot,
60
61    /// State after the operation (if applicable)
62    pub after: Option<ContextSnapshot>,
63
64    /// Surrounding context for understanding the change
65    pub surrounding: Vec<ContextLine>,
66
67    /// Primary location where the operation occurred
68    pub location: SourceLocation,
69
70    /// Scope of the operation (file, function, block, etc.)
71    pub scope: OperationScope,
72
73    /// Language-specific context
74    pub language_context: Option<LanguageContext>,
75
76    /// Project-level context
77    pub project_context: Option<ProjectContext>,
78}
79
80/// Snapshot of state at a specific point in time
81#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct ContextSnapshot {
83    /// Content at the time of snapshot
84    pub content: String,
85
86    /// Timestamp when the snapshot was taken
87    pub timestamp: SystemTime,
88
89    /// Hash or checksum of the content for integrity
90    pub content_hash: String,
91
92    /// AST representation if available
93    pub ast_summary: Option<ComprehensiveAstSummary>,
94
95    /// Symbols present at this point
96    pub symbols: Vec<ComprehensiveSymbol>,
97}
98
99/// A line of context with metadata
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct ContextLine {
102    /// Line number (1-based)
103    pub line_number: usize,
104
105    /// Content of the line
106    pub content: String,
107
108    /// Type of context this line represents
109    pub line_type: ContextLineType,
110
111    /// Indentation level for formatting preservation
112    pub indentation: usize,
113
114    /// Whether this line was modified
115    pub modified: bool,
116}
117
118/// Types of context lines
119#[derive(Debug, Clone, Serialize, Deserialize)]
120pub enum ContextLineType {
121    /// Line before the operation
122    Before,
123    /// Line after the operation
124    After,
125    /// Line that was changed
126    Changed,
127    /// Line added by the operation
128    Added,
129    /// Line removed by the operation
130    Removed,
131    /// Separator or structural element
132    Separator,
133}
134
135/// Represents a single change made during an operation
136#[derive(Debug, Clone, Serialize, Deserialize)]
137pub struct Change {
138    /// Unique identifier for this change
139    pub id: Uuid,
140
141    /// Type and nature of the change
142    pub kind: ChangeKind,
143
144    /// Original content (if any)
145    pub old: Option<String>,
146
147    /// New content (if any)
148    pub new: Option<String>,
149
150    /// Line range affected by the change
151    pub line_range: Range<usize>,
152
153    /// Character range within the file
154    pub char_range: Range<usize>,
155
156    /// Location where the change occurred
157    pub location: SourceLocation,
158
159    /// Semantic impact of this change
160    pub semantic_impact: ComprehensiveSemanticImpact,
161
162    /// Symbols affected by this change
163    pub affected_symbols: Vec<String>,
164
165    /// Confidence level (0.0 to 1.0)
166    pub confidence: f32,
167
168    /// Human-readable description
169    pub description: String,
170}
171
172/// Types of changes with rich semantic information
173#[derive(Debug, Clone, Serialize, Deserialize)]
174pub enum ChangeKind {
175    /// Content was added
176    Added {
177        reason: String,
178        insertion_point: SourceLocation,
179    },
180
181    /// Content was modified
182    Modified {
183        why: String,
184        modification_type: ModificationType,
185    },
186
187    /// Content was deleted
188    Deleted {
189        justification: String,
190        preservation_note: Option<String>,
191    },
192
193    /// Code was refactored (structural change preserving behavior)
194    Refactored {
195        from_pattern: String,
196        to_pattern: String,
197        refactor_type: RefactorType,
198    },
199
200    /// Content was moved from one location to another
201    Moved {
202        from: SourceLocation,
203        to: SourceLocation,
204        move_reason: String,
205    },
206
207    /// Symbol was renamed
208    Renamed {
209        old_name: String,
210        new_name: String,
211        symbol_type: String,
212    },
213
214    /// Import or dependency was added/removed/modified
215    ImportChanged {
216        import_type: ImportChangeType,
217        module_name: String,
218        impact: String,
219    },
220}
221
222/// Types of modifications
223#[derive(Debug, Clone, Serialize, Deserialize)]
224pub enum ModificationType {
225    /// Content replacement
226    Replacement,
227    /// Parameter change
228    ParameterChange,
229    /// Type change
230    TypeChange,
231    /// Logic enhancement
232    LogicEnhancement,
233    /// Performance optimization
234    Optimization,
235    /// Bug fix
236    BugFix,
237    /// Formatting change
238    Formatting,
239}
240
241/// Types of refactoring
242#[derive(Debug, Clone, Serialize, Deserialize)]
243pub enum RefactorType {
244    /// Extract method/function
245    ExtractMethod,
246    /// Inline method/function
247    InlineMethod,
248    /// Move method/function
249    MoveMethod,
250    /// Rename symbol
251    RenameSymbol,
252    /// Extract variable
253    ExtractVariable,
254    /// Extract constant
255    ExtractConstant,
256    /// Change method signature
257    ChangeSignature,
258    /// Convert to/from lambda
259    LambdaConversion,
260}
261
262/// Import/dependency changes
263#[derive(Debug, Clone, Serialize, Deserialize)]
264pub enum ImportChangeType {
265    Added,
266    Removed,
267    Modified,
268    Reorganized,
269}
270
271/// Comprehensive semantic impact analysis of changes
272#[derive(Debug, Clone, Serialize, Deserialize)]
273pub struct ComprehensiveSemanticImpact {
274    /// Level of impact
275    pub level: ImpactLevel,
276
277    /// Scope of the impact
278    pub scope: ImpactScope,
279
280    /// Breaking change analysis
281    pub breaking_changes: Vec<BreakingChange>,
282
283    /// API compatibility assessment
284    pub api_compatibility: ApiCompatibility,
285
286    /// Performance implications
287    pub performance_impact: ComprehensivePerformanceImpact,
288
289    /// Security implications
290    pub security_impact: SecurityImpact,
291
292    /// Test impact analysis
293    pub test_impact: TestImpact,
294}
295
296/// Levels of impact
297#[derive(Debug, Clone, Serialize, Deserialize)]
298pub enum ImpactLevel {
299    /// No significant impact
300    None,
301    /// Impact contained to immediate context
302    Local,
303    /// Impact affects module/file interface
304    Interface,
305    /// Impact affects overall system architecture
306    Architectural,
307    /// Impact requires careful review
308    Critical,
309}
310
311/// Scope of impact
312#[derive(Debug, Clone, Serialize, Deserialize)]
313pub enum ImpactScope {
314    /// Single line/statement
315    Statement,
316    /// Single function/method
317    Function,
318    /// Single class/struct
319    Class,
320    /// Single file/module
321    Module,
322    /// Multiple files
323    Package,
324    /// Entire project
325    Project,
326    /// External dependencies
327    Dependencies,
328}
329
330/// Breaking change analysis
331#[derive(Debug, Clone, Serialize, Deserialize)]
332pub struct BreakingChange {
333    /// Description of the breaking change
334    pub description: String,
335
336    /// Affected API elements
337    pub affected_apis: Vec<String>,
338
339    /// Migration strategy
340    pub migration_strategy: Option<String>,
341
342    /// Severity of the break
343    pub severity: BreakingSeverity,
344}
345
346/// Severity of breaking changes
347#[derive(Debug, Clone, Serialize, Deserialize)]
348pub enum BreakingSeverity {
349    /// Minor breaking change
350    Minor,
351    /// Major breaking change requiring updates
352    Major,
353    /// Critical breaking change requiring significant refactoring
354    Critical,
355}
356
357/// API compatibility assessment
358#[derive(Debug, Clone, Serialize, Deserialize)]
359pub struct ApiCompatibility {
360    /// Whether the change is backward compatible
361    pub backward_compatible: bool,
362
363    /// Version compatibility level
364    pub version_impact: VersionImpact,
365
366    /// Deprecated features affected
367    pub deprecated_usage: Vec<String>,
368
369    /// New features introduced
370    pub new_features: Vec<String>,
371}
372
373/// Version impact levels
374#[derive(Debug, Clone, Serialize, Deserialize)]
375pub enum VersionImpact {
376    /// Patch version (bug fixes)
377    Patch,
378    /// Minor version (new features, backward compatible)
379    Minor,
380    /// Major version (breaking changes)
381    Major,
382}
383
384/// Comprehensive performance impact analysis
385#[derive(Debug, Clone, Serialize, Deserialize)]
386pub struct ComprehensivePerformanceImpact {
387    /// Expected performance change
388    pub expected_change: PerformanceChange,
389
390    /// Complexity analysis
391    pub complexity_change: Option<ComplexityChange>,
392
393    /// Memory usage impact
394    pub memory_impact: MemoryImpact,
395
396    /// CPU usage impact
397    pub cpu_impact: String,
398
399    /// I/O impact
400    pub io_impact: String,
401}
402
403/// Expected performance changes
404#[derive(Debug, Clone, Serialize, Deserialize)]
405pub enum PerformanceChange {
406    /// Significant improvement
407    Improvement(String),
408    /// No significant change
409    Neutral,
410    /// Performance degradation
411    Degradation(String),
412    /// Unknown impact
413    Unknown,
414}
415
416/// Complexity analysis changes
417#[derive(Debug, Clone, Serialize, Deserialize)]
418pub struct ComplexityChange {
419    /// Time complexity before -> after
420    pub time_complexity: (String, String),
421
422    /// Space complexity before -> after
423    pub space_complexity: (String, String),
424
425    /// Cyclomatic complexity change
426    pub cyclomatic_complexity_delta: i32,
427}
428
429/// Memory usage impact
430#[derive(Debug, Clone, Serialize, Deserialize)]
431pub struct MemoryImpact {
432    /// Estimated memory change in bytes
433    pub estimated_bytes_delta: Option<i64>,
434
435    /// Allocation pattern changes
436    pub allocation_changes: Vec<String>,
437
438    /// Memory leak risks
439    pub leak_risks: Vec<String>,
440}
441
442/// Security impact analysis
443#[derive(Debug, Clone, Serialize, Deserialize)]
444pub struct SecurityImpact {
445    /// Security level assessment
446    pub level: SecurityLevel,
447
448    /// Potential vulnerabilities introduced
449    pub vulnerabilities: Vec<SecurityVulnerability>,
450
451    /// Security improvements
452    pub improvements: Vec<String>,
453
454    /// Required security review
455    pub requires_review: bool,
456}
457
458/// Security impact levels
459#[derive(Debug, Clone, Serialize, Deserialize)]
460pub enum SecurityLevel {
461    /// No security impact
462    None,
463    /// Low security impact
464    Low,
465    /// Medium security impact
466    Medium,
467    /// High security impact requiring review
468    High,
469    /// Critical security impact requiring immediate review
470    Critical,
471}
472
473/// Security vulnerability description
474#[derive(Debug, Clone, Serialize, Deserialize)]
475pub struct SecurityVulnerability {
476    /// Vulnerability type (e.g., "SQL Injection", "XSS")
477    pub vulnerability_type: String,
478
479    /// Description of the vulnerability
480    pub description: String,
481
482    /// Severity level
483    pub severity: SecurityLevel,
484
485    /// Mitigation strategies
486    pub mitigation: Vec<String>,
487}
488
489/// Test impact analysis
490#[derive(Debug, Clone, Serialize, Deserialize)]
491pub struct TestImpact {
492    /// Tests that may be affected
493    pub affected_tests: Vec<String>,
494
495    /// New tests required
496    pub required_tests: Vec<String>,
497
498    /// Test coverage impact
499    pub coverage_impact: CoverageImpact,
500
501    /// Test categories affected
502    pub test_categories: Vec<TestCategory>,
503}
504
505/// Test coverage impact
506#[derive(Debug, Clone, Serialize, Deserialize)]
507pub struct CoverageImpact {
508    /// Expected coverage change (percentage points)
509    pub coverage_delta: Option<f32>,
510
511    /// New uncovered lines
512    pub uncovered_lines: Vec<usize>,
513
514    /// Coverage recommendations
515    pub recommendations: Vec<String>,
516}
517
518/// Categories of tests
519#[derive(Debug, Clone, Serialize, Deserialize)]
520pub enum TestCategory {
521    Unit,
522    Integration,
523    EndToEnd,
524    Performance,
525    Security,
526    Regression,
527}
528
529/// Scope of an operation
530#[derive(Debug, Clone, Serialize, Deserialize)]
531pub struct OperationScope {
532    /// Type of scope
533    pub scope_type: ScopeType,
534
535    /// Name or identifier of the scope
536    pub name: String,
537
538    /// Hierarchical path (e.g., "module::class::function")
539    pub path: Vec<String>,
540
541    /// File path where the scope is defined
542    pub file_path: PathBuf,
543
544    /// Line range of the scope
545    pub line_range: Range<usize>,
546}
547
548/// Types of operation scopes
549#[derive(Debug, Clone, Serialize, Deserialize)]
550pub enum ScopeType {
551    /// Global scope
552    Global,
553    /// File/module scope
554    File,
555    /// Namespace scope
556    Namespace,
557    /// Class/struct scope
558    Class,
559    /// Function/method scope
560    Function,
561    /// Block scope
562    Block,
563    /// Expression scope
564    Expression,
565}
566
567/// Language-specific context information
568#[derive(Debug, Clone, Serialize, Deserialize)]
569pub struct LanguageContext {
570    /// Programming language
571    pub language: Language,
572
573    /// Language version or standard
574    pub version: Option<String>,
575
576    /// Language-specific features used
577    pub features: Vec<String>,
578
579    /// Framework or library context
580    pub frameworks: Vec<String>,
581
582    /// Compilation or runtime context
583    pub runtime_context: Vec<String>,
584}
585
586/// Project-level context information
587#[derive(Debug, Clone, Serialize, Deserialize)]
588pub struct ProjectContext {
589    /// Project name
590    pub name: Option<String>,
591
592    /// Project type (library, application, etc.)
593    pub project_type: Option<String>,
594
595    /// Build system (Cargo, npm, Maven, etc.)
596    pub build_system: Option<String>,
597
598    /// Dependencies affected
599    pub dependencies: Vec<DependencyInfo>,
600
601    /// Configuration files affected
602    pub config_files: Vec<PathBuf>,
603}
604
605/// Dependency information
606#[derive(Debug, Clone, Serialize, Deserialize)]
607pub struct DependencyInfo {
608    /// Dependency name
609    pub name: String,
610
611    /// Version constraint
612    pub version: Option<String>,
613
614    /// Type of dependency (runtime, dev, build, etc.)
615    pub dependency_type: String,
616
617    /// Whether this is a new, modified, or removed dependency
618    pub change_type: String,
619}
620
621/// Comprehensive operation metadata
622#[derive(Debug, Clone, Serialize, Deserialize)]
623pub struct OperationMetadata {
624    /// Tool that performed the operation
625    pub tool: String,
626
627    /// Specific operation performed
628    pub operation: String,
629
630    /// Operation ID for tracking
631    pub operation_id: Uuid,
632
633    /// Timestamp when operation started
634    pub started_at: SystemTime,
635
636    /// Timestamp when operation completed
637    pub completed_at: SystemTime,
638
639    /// Confidence score (0.0 to 1.0)
640    pub confidence: f32,
641
642    /// Operation parameters
643    pub parameters: HashMap<String, String>,
644
645    /// Tool version
646    pub tool_version: String,
647
648    /// User or agent that initiated the operation
649    pub initiated_by: Option<String>,
650
651    /// Session or context ID
652    pub session_id: Option<Uuid>,
653}
654
655/// Performance metrics for operations
656#[derive(Debug, Clone, Serialize, Deserialize)]
657pub struct PerformanceMetrics {
658    /// Total execution time
659    pub execution_time: Duration,
660
661    /// Time breakdown by operation phase
662    pub phase_times: HashMap<String, Duration>,
663
664    /// Memory usage statistics
665    pub memory_usage: MemoryUsage,
666
667    /// CPU usage statistics
668    pub cpu_usage: CpuUsage,
669
670    /// I/O statistics
671    pub io_stats: IoStats,
672
673    /// Caching statistics
674    pub cache_stats: CacheStats,
675}
676
677/// Memory usage statistics
678#[derive(Debug, Clone, Serialize, Deserialize)]
679pub struct MemoryUsage {
680    /// Peak memory usage in bytes
681    pub peak_bytes: u64,
682
683    /// Average memory usage in bytes
684    pub average_bytes: u64,
685
686    /// Number of allocations
687    pub allocations: u64,
688
689    /// Number of deallocations
690    pub deallocations: u64,
691
692    /// Memory efficiency score (0.0 to 1.0)
693    pub efficiency_score: f32,
694}
695
696/// CPU usage statistics
697#[derive(Debug, Clone, Serialize, Deserialize)]
698pub struct CpuUsage {
699    /// CPU time used
700    pub cpu_time: Duration,
701
702    /// CPU utilization percentage
703    pub utilization_percent: f32,
704
705    /// Number of context switches
706    pub context_switches: u64,
707}
708
709/// I/O statistics
710#[derive(Debug, Clone, Serialize, Deserialize)]
711pub struct IoStats {
712    /// Bytes read from storage
713    pub bytes_read: u64,
714
715    /// Bytes written to storage
716    pub bytes_written: u64,
717
718    /// Number of read operations
719    pub read_ops: u64,
720
721    /// Number of write operations
722    pub write_ops: u64,
723
724    /// I/O wait time
725    pub io_wait_time: Duration,
726}
727
728/// Caching statistics
729#[derive(Debug, Clone, Serialize, Deserialize)]
730pub struct CacheStats {
731    /// Cache hit rate (0.0 to 1.0)
732    pub hit_rate: f32,
733
734    /// Number of cache hits
735    pub hits: u64,
736
737    /// Number of cache misses
738    pub misses: u64,
739
740    /// Cache size in entries
741    pub cache_size: u64,
742
743    /// Cache efficiency score (0.0 to 1.0)
744    pub efficiency_score: f32,
745}
746
747/// Diagnostic information (warnings, errors, info)
748#[derive(Debug, Clone, Serialize, Deserialize)]
749pub struct Diagnostic {
750    /// Diagnostic level
751    pub level: DiagnosticLevel,
752
753    /// Diagnostic message
754    pub message: String,
755
756    /// Location where the diagnostic applies
757    pub location: Option<SourceLocation>,
758
759    /// Error code or identifier
760    pub _code: Option<String>,
761
762    /// Suggestions for resolution
763    pub suggestions: Vec<String>,
764
765    /// Related diagnostics
766    pub related: Vec<Uuid>,
767}
768
769/// Levels of diagnostics
770#[derive(Debug, Clone, Serialize, Deserialize)]
771pub enum DiagnosticLevel {
772    /// Informational message
773    Info,
774    /// Warning that should be addressed
775    Warning,
776    /// Error that must be fixed
777    Error,
778    /// Hint or suggestion
779    Hint,
780}
781
782/// Comprehensive AST summary for structural understanding
783#[derive(Debug, Clone, Serialize, Deserialize)]
784pub struct ComprehensiveAstSummary {
785    /// Root node type
786    pub root_type: String,
787
788    /// Number of nodes in the AST
789    pub node_count: usize,
790
791    /// Maximum depth of the AST
792    pub max_depth: usize,
793
794    /// Top-level symbols
795    pub symbols: Vec<ComprehensiveSymbol>,
796
797    /// Complexity metrics
798    pub complexity: ComplexityMetrics,
799
800    /// AST hash for comparison
801    pub ast_hash: String,
802}
803
804/// Comprehensive symbol information
805#[derive(Debug, Clone, Serialize, Deserialize)]
806pub struct ComprehensiveSymbol {
807    /// Symbol name
808    pub name: String,
809
810    /// Symbol type (function, class, variable, etc.)
811    pub symbol_type: SymbolType,
812
813    /// Location where the symbol is defined
814    pub location: SourceLocation,
815
816    /// Visibility (public, private, etc.)
817    pub visibility: Visibility,
818
819    /// Symbol signature (for functions, methods)
820    pub signature: Option<String>,
821
822    /// Documentation or comments
823    pub documentation: Option<String>,
824}
825
826/// Types of symbols
827#[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/// Symbol visibility levels
844#[derive(Debug, Clone, Serialize, Deserialize)]
845pub enum Visibility {
846    Public,
847    Private,
848    Protected,
849    Internal,
850    PackagePrivate,
851}
852
853/// Code complexity metrics
854#[derive(Debug, Clone, Serialize, Deserialize)]
855pub struct ComplexityMetrics {
856    /// Cyclomatic complexity
857    pub cyclomatic: u32,
858
859    /// Cognitive complexity
860    pub cognitive: u32,
861
862    /// Halstead complexity metrics
863    pub halstead: Option<HalsteadMetrics>,
864
865    /// Lines of code
866    pub lines_of_code: u32,
867
868    /// Number of functions/methods
869    pub function_count: u32,
870
871    /// Nesting depth
872    pub max_nesting_depth: u32,
873}
874
875/// Halstead complexity metrics
876#[derive(Debug, Clone, Serialize, Deserialize)]
877pub struct HalsteadMetrics {
878    /// Number of distinct operators
879    pub distinct_operators: u32,
880
881    /// Number of distinct operands
882    pub distinct_operands: u32,
883
884    /// Total number of operators
885    pub total_operators: u32,
886
887    /// Total number of operands
888    pub total_operands: u32,
889
890    /// Program vocabulary
891    pub vocabulary: u32,
892
893    /// Program length
894    pub length: u32,
895
896    /// Calculated volume
897    pub volume: f64,
898
899    /// Difficulty level
900    pub difficulty: f64,
901
902    /// Effort required
903    pub effort: f64,
904}
905
906// Extension traits for easier usage
907
908/// Extension trait for Result<T, E> to easily convert to ComprehensiveToolOutput
909pub trait ResultExt<T, E> {
910    /// Convert a Result to a ComprehensiveToolOutput
911    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
941// Helper methods for building outputs
942impl<T> ComprehensiveToolOutput<T> {
943    /// Create a new ComprehensiveToolOutput with minimal required fields
944    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    /// Add a change to the output
971    pub fn add_change(mut self, change: Change) -> Self {
972        self.changes.push(change);
973        self
974    }
975
976    /// Add multiple changes to the output
977    pub fn add_changes(mut self, changes: Vec<Change>) -> Self {
978        self.changes.extend(changes);
979        self
980    }
981
982    /// Add a diagnostic message
983    pub fn add_diagnostic(mut self, diagnostic: Diagnostic) -> Self {
984        self.diagnostics.push(diagnostic);
985        self
986    }
987
988    /// Set the summary
989    pub fn with_summary(mut self, summary: String) -> Self {
990        self.summary = summary;
991        self
992    }
993
994    /// Set the confidence level
995    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    /// Check if the operation had any errors
1001    pub fn has_errors(&self) -> bool {
1002        self.diagnostics
1003            .iter()
1004            .any(|d| matches!(d.level, DiagnosticLevel::Error))
1005    }
1006
1007    /// Check if the operation had any warnings
1008    pub fn has_warnings(&self) -> bool {
1009        self.diagnostics
1010            .iter()
1011            .any(|d| matches!(d.level, DiagnosticLevel::Warning))
1012    }
1013
1014    /// Get the highest impact level of all changes
1015    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    /// Create minimal operation context
1033    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    /// Create an empty context snapshot
1048    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    /// Create minimal operation scope
1061    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    /// Create a simple addition change
1133    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    /// Create a simple modification change
1153    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    /// Create a simple deletion change
1178    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    /// Create minimal semantic impact
1200    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    /// Create compatible API compatibility
1215    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    /// Create neutral performance impact
1227    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    /// Create neutral memory impact
1240    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    /// Create no security impact
1251    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    /// Create minimal test impact
1263    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    /// Create neutral coverage impact
1275    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    /// Create an info diagnostic
1286    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    /// Create a warning diagnostic
1298    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    /// Create an error diagnostic
1310    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    /// Add a suggestion to the diagnostic
1322    pub fn with_suggestion(mut self, suggestion: String) -> Self {
1323        self.suggestions.push(suggestion);
1324        self
1325    }
1326
1327    /// Set the location for the diagnostic
1328    pub fn at_location(mut self, location: SourceLocation) -> Self {
1329        self.location = Some(location);
1330        self
1331    }
1332
1333    /// Set the error code
1334    pub fn with_code(mut self, code: String) -> Self {
1335        self._code = Some(code);
1336        self
1337    }
1338}
1339
1340// Builder patterns for convenient output construction
1341
1342/// Builder for constructing ComprehensiveToolOutput instances
1343pub 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    /// Create a new output builder
1358    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    /// Add a change to the output
1374    pub fn change(mut self, change: Change) -> Self {
1375        self.changes.push(change);
1376        self
1377    }
1378
1379    /// Add multiple changes
1380    pub fn changes(mut self, changes: Vec<Change>) -> Self {
1381        self.changes.extend(changes);
1382        self
1383    }
1384
1385    /// Add a diagnostic
1386    pub fn diagnostic(mut self, diagnostic: Diagnostic) -> Self {
1387        self.diagnostics.push(diagnostic);
1388        self
1389    }
1390
1391    /// Add an info diagnostic
1392    pub fn info(mut self, message: String) -> Self {
1393        self.diagnostics.push(Diagnostic::info(message));
1394        self
1395    }
1396
1397    /// Add a warning diagnostic
1398    pub fn warning(mut self, message: String) -> Self {
1399        self.diagnostics.push(Diagnostic::warning(message));
1400        self
1401    }
1402
1403    /// Add an error diagnostic
1404    pub fn error(mut self, message: String) -> Self {
1405        self.diagnostics.push(Diagnostic::error(message));
1406        self
1407    }
1408
1409    /// Set the confidence level
1410    pub const fn confidence(mut self, confidence: f32) -> Self {
1411        self.confidence = confidence.clamp(0.0, 1.0);
1412        self
1413    }
1414
1415    /// Set the summary
1416    pub fn summary(mut self, summary: String) -> Self {
1417        self.summary = Some(summary);
1418        self
1419    }
1420
1421    /// Set the operation context
1422    pub fn context(mut self, context: OperationContext) -> Self {
1423        self.context = Some(context);
1424        self
1425    }
1426
1427    /// Set performance metrics
1428    pub fn performance(mut self, performance: PerformanceMetrics) -> Self {
1429        self.performance = Some(performance);
1430        self
1431    }
1432
1433    /// Build the final ComprehensiveToolOutput
1434    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
1481/// Builder for constructing Change instances
1482pub 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    /// Create a new change builder
1494    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    /// Set the old content
1507    pub fn old_content(mut self, content: String) -> Self {
1508        self.old = Some(content);
1509        self
1510    }
1511
1512    /// Set the new content
1513    pub fn new_content(mut self, content: String) -> Self {
1514        self.new = Some(content);
1515        self
1516    }
1517
1518    /// Set the description
1519    pub fn description(mut self, description: String) -> Self {
1520        self.description = Some(description);
1521        self
1522    }
1523
1524    /// Set the confidence
1525    pub const fn confidence(mut self, confidence: f32) -> Self {
1526        self.confidence = confidence.clamp(0.0, 1.0);
1527        self
1528    }
1529
1530    /// Add an affected symbol
1531    pub fn symbol(mut self, symbol: String) -> Self {
1532        self.affected_symbols.push(symbol);
1533        self
1534    }
1535
1536    /// Set the semantic impact
1537    pub fn impact(mut self, impact: ComprehensiveSemanticImpact) -> Self {
1538        self.impact = Some(impact);
1539        self
1540    }
1541
1542    /// Build an addition change
1543    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    /// Build a modification change
1568    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    /// Build a deletion change
1593    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
1618// Convenience functions for common scenarios
1619
1620/// Create a simple successful output for tools that don't need complex analysis
1621pub 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
1633/// Create a simple error output for tools that encounter failures
1634pub 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
1647/// Create an output with a single file modification
1648pub 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
1674/// Create an output with multiple file changes
1675pub 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
1699/// Performance timing helper for measuring tool operations
1700pub 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    /// Create a new performance timer
1709    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    /// Start timing a specific phase
1719    pub fn start_phase(&mut self, phase_name: String) {
1720        // Start new phase
1721        self.current_phase = Some(phase_name);
1722        self.current_phase_start = Some(SystemTime::now());
1723    }
1724
1725    /// End the current phase
1726    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    /// Get the elapsed time since the timer was created
1736    pub fn elapsed(&self) -> Duration {
1737        self.started_at.elapsed().unwrap_or_default()
1738    }
1739
1740    /// Get the performance metrics
1741    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}