Skip to main content

codelens_engine/
ir.rs

1//! Canonical semantic IR types for downstream consumers.
2//!
3//! This module provides a unified set of types that represent the semantic
4//! structure of a codebase — relationships between symbols, call graph edges,
5//! impact analysis nodes, and structured edit plans.
6//!
7//! # Re-exports
8//!
9//! Core types from other engine modules are re-exported here so that consumers
10//! can import everything from a single location:
11//!
12//! ```rust
13//! use codelens_engine::ir::{SymbolInfo, Relation, ImpactNode, EditPlan};
14//! ```
15
16use serde::Serialize;
17
18// Re-exports of existing types from other engine modules.
19pub use crate::circular::CircularDependency;
20pub use crate::git::ChangedFile;
21pub use crate::lsp::types::LspDiagnostic;
22pub use crate::rename::RenameEdit;
23pub use crate::search::SearchResult;
24pub use crate::symbols::{RankedContextEntry, SymbolInfo, SymbolKind};
25
26// ---------------------------------------------------------------------------
27// Relation graph types
28// ---------------------------------------------------------------------------
29
30/// A directed relationship between two symbols or files.
31#[derive(Debug, Clone, Serialize)]
32pub struct Relation {
33    /// Source symbol ID or file path.
34    pub source: String,
35    /// Target symbol ID or file path.
36    pub target: String,
37    pub kind: RelationKind,
38    /// File where the relation was observed, if applicable.
39    pub file_path: Option<String>,
40    /// Line number where the relation was observed, if applicable.
41    pub line: Option<usize>,
42}
43
44/// The kind of directed relationship between two symbols or files.
45#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
46pub enum RelationKind {
47    /// Function calls function.
48    Calls,
49    /// Reverse of `Calls`.
50    CalledBy,
51    /// File imports file.
52    Imports,
53    /// Reverse of `Imports`.
54    ImportedBy,
55    /// Class extends class.
56    Inherits,
57    /// Class implements interface.
58    Implements,
59    /// Symbol references symbol.
60    References,
61    /// File or module contains symbol.
62    Contains,
63}
64
65// ---------------------------------------------------------------------------
66// Call graph edge
67// ---------------------------------------------------------------------------
68
69/// A call graph edge with optional metadata.
70///
71/// Note: the engine's lower-level [`crate::call_graph::CallEdge`] carries
72/// confidence and resolution strategy fields.  This IR type is the
73/// schema-facing, minimal form used in output payloads.
74#[derive(Debug, Clone, Serialize)]
75pub struct IrCallEdge {
76    /// Caller symbol name or ID.
77    pub caller: String,
78    /// Callee symbol name or ID.
79    pub callee: String,
80    pub caller_file: String,
81    pub callee_file: Option<String>,
82    pub line: usize,
83}
84
85// ---------------------------------------------------------------------------
86// Impact analysis graph
87// ---------------------------------------------------------------------------
88
89/// A node in an impact analysis graph.
90#[derive(Debug, Clone, Serialize)]
91pub struct ImpactNode {
92    pub file_path: String,
93    /// Symbol name within the file, if the node represents a symbol.
94    pub symbol: Option<String>,
95    /// Distance from the change origin (0 = directly changed).
96    pub depth: usize,
97    pub impact_kind: ImpactKind,
98    /// Count of symbols affected within this file.
99    pub affected_symbols: usize,
100}
101
102/// How a file or symbol is affected by a change.
103#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
104pub enum ImpactKind {
105    /// Directly changed.
106    Direct,
107    /// Calls something that changed.
108    Caller,
109    /// Imports something that changed.
110    Importer,
111    /// Inherits or implements something that changed.
112    TypeChild,
113    /// Indirectly affected (transitive dependency).
114    Transitive,
115}
116
117// ---------------------------------------------------------------------------
118// Structured edit plan
119// ---------------------------------------------------------------------------
120
121/// A structured edit plan for multi-file changes.
122#[derive(Debug, Clone, Serialize)]
123pub struct EditPlan {
124    pub description: String,
125    pub edits: Vec<EditAction>,
126}
127
128/// A single edit action within an [`EditPlan`].
129#[derive(Debug, Clone, Serialize)]
130pub struct EditAction {
131    pub file_path: String,
132    pub kind: EditActionKind,
133    /// Target line for `Insert` and `Replace` actions.
134    pub line: Option<usize>,
135    /// Original text to replace (used for `Replace` and `Delete`).
136    pub old_text: Option<String>,
137    /// Replacement or inserted text.
138    pub new_text: String,
139}
140
141/// The kind of edit performed by an [`EditAction`].
142#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
143pub enum EditActionKind {
144    Insert,
145    Replace,
146    Delete,
147    /// Create a new file.
148    Create,
149}
150
151// ---------------------------------------------------------------------------
152// Retrieval pipeline types
153// ---------------------------------------------------------------------------
154
155/// Describes a stage in the retrieval pipeline.
156///
157/// The full pipeline is: `Lexical → SymbolScore → DenseRetrieval → Rerank → GraphExpand`
158///
159/// Each stage can be enabled/disabled and contributes a weighted score.
160#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
161pub enum RetrievalStage {
162    /// FTS5 / BM25 corpus search — file-level pre-filtering.
163    Lexical,
164    /// Symbol name/signature scoring — AST-aware matching.
165    SymbolScore,
166    /// Embedding-based dense retrieval — semantic similarity.
167    DenseRetrieval,
168    /// Multi-signal blending — text + pagerank + recency + semantic.
169    Rerank,
170    /// Graph expansion — callers, importers, type hierarchy of top results.
171    GraphExpand,
172}
173
174/// Configuration for a retrieval pipeline run.
175#[derive(Debug, Clone, Serialize)]
176pub struct RetrievalConfig {
177    /// Which stages are enabled.
178    pub stages: Vec<RetrievalStage>,
179    /// Maximum results to return.
180    pub max_results: usize,
181    /// Token budget for response.
182    pub token_budget: usize,
183    /// Whether to include symbol bodies.
184    pub include_body: bool,
185    /// Weight overrides per stage (default: equal weighting).
186    pub weights: RetrievalWeights,
187}
188
189/// Weights for each retrieval signal in the rerank stage.
190#[derive(Debug, Clone, Serialize)]
191pub struct RetrievalWeights {
192    pub text: f64,
193    pub pagerank: f64,
194    pub recency: f64,
195    pub semantic: f64,
196}
197
198impl Default for RetrievalWeights {
199    fn default() -> Self {
200        Self {
201            text: 0.40,
202            pagerank: 0.20,
203            recency: 0.10,
204            semantic: 0.30,
205        }
206    }
207}
208
209impl Default for RetrievalConfig {
210    fn default() -> Self {
211        Self {
212            stages: vec![
213                RetrievalStage::Lexical,
214                RetrievalStage::SymbolScore,
215                RetrievalStage::DenseRetrieval,
216                RetrievalStage::Rerank,
217            ],
218            max_results: 20,
219            token_budget: 4000,
220            include_body: true,
221            weights: RetrievalWeights::default(),
222        }
223    }
224}