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}