aptu_coder_core/lib.rs
1// SPDX-FileCopyrightText: 2026 aptu-coder contributors
2// SPDX-License-Identifier: Apache-2.0
3//! Multi-language code structure analysis library using tree-sitter.
4//!
5//! This crate provides core analysis functionality for extracting code structure
6//! from multiple programming languages. It is designed to be used as a library
7//! by MCP servers and other tools.
8//!
9//! # Features
10//!
11//! - **Language support**: Rust, Go, Java, Python, TypeScript, TSX, Fortran, JavaScript, C/C++, C# (feature-gated)
12//! - **Schema generation**: Optional JSON schema support via the `schemars` feature
13//! - **Async-friendly**: Uses tokio for concurrent analysis
14//! - **Cancellation support**: Built-in cancellation token support
15//!
16//! # Examples
17//!
18//! ```no_run
19//! use aptu_coder_core::analyze::analyze_directory;
20//! use std::path::Path;
21//!
22//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
23//! let output = analyze_directory(Path::new("src"), None)?;
24//! println!("Files: {:?}", output.files.len());
25//! # Ok(())
26//! # }
27//! ```
28
29#![cfg_attr(test, allow(clippy::unwrap_used))]
30
31pub mod analyze;
32pub mod cache;
33pub mod completion;
34mod config;
35pub mod edit;
36pub mod formatter;
37pub mod formatter_defuse;
38pub mod graph;
39pub mod lang;
40pub mod languages;
41pub mod pagination;
42pub mod parser;
43pub mod test_detection;
44pub mod traversal;
45pub mod types;
46
47#[cfg(feature = "schemars")]
48pub mod schema_helpers;
49
50pub(crate) const EXCLUDED_DIRS: &[&str] = &[
51 "node_modules",
52 "vendor",
53 ".git",
54 "__pycache__",
55 "target",
56 "dist",
57 "build",
58 ".venv",
59];
60
61// Re-exports of key public APIs
62pub use analyze::{
63 AnalysisOutput, AnalyzeError, CallChainEntry, FileAnalysisOutput, FocusedAnalysisConfig,
64 FocusedAnalysisOutput, analyze_directory, analyze_directory_with_progress, analyze_file,
65 analyze_focused, analyze_focused_with_progress, analyze_focused_with_progress_with_entries,
66 analyze_module_file, analyze_str,
67};
68pub use config::AnalysisConfig;
69pub use edit::{EditError, edit_overwrite_content, edit_replace_block};
70pub use lang::{language_for_extension, supported_languages};
71pub use parser::ParserError;
72pub use types::{
73 AnalysisMode, AnalysisResult, AnalyzeDirectoryParams, AnalyzeFileField, AnalyzeFileParams,
74 AnalyzeModuleParams, AnalyzeSymbolParams, CallChain, CallEdge, CallInfo, ClassInfo, DefUseKind,
75 DefUseSite, EditOverwriteOutput, EditOverwriteParams, EditReplaceOutput, EditReplaceParams,
76 ErrorMeta, ExecCommandParams, FileInfo, FocusedAnalysisData, FunctionInfo, ImplTraitInfo,
77 ImportInfo, ModuleFunctionInfo, ModuleImportInfo, ModuleInfo, OutputControlParams,
78 PaginationParams, ReferenceInfo, ReferenceType, STDIN_MAX_BYTES, SemanticAnalysis, ShellOutput,
79 SymbolMatchMode,
80};
81
82/// Captures from a custom tree-sitter query.
83#[derive(Debug, Clone, PartialEq, Eq, Hash)]
84pub struct QueryCapture {
85 /// The capture name from the query (without leading `@`).
86 pub capture_name: String,
87 /// The matched source text.
88 pub text: String,
89 /// Start line (0-indexed).
90 pub start_line: usize,
91 /// End line (0-indexed, inclusive).
92 pub end_line: usize,
93 /// Start byte offset.
94 pub start_byte: usize,
95 /// End byte offset.
96 pub end_byte: usize,
97}
98
99/// Execute a custom tree-sitter query against source code.
100///
101/// # Arguments
102///
103/// * `language` - Language name (e.g., "rust", "python"). Must be an enabled language feature.
104/// * `source` - Source code to query.
105/// * `query` - A tree-sitter query string (S-expression syntax).
106///
107/// # Returns
108///
109/// A vector of [`QueryCapture`] results, or a [`ParserError`] if the query is malformed
110/// or the language is not supported.
111///
112/// # Security note
113///
114/// This function accepts user-controlled `query` strings. Pathological queries against
115/// large `source` inputs may cause CPU exhaustion. Callers in untrusted environments
116/// should bound the length of both `source` and `query` before calling this function.
117/// `Query::new()` returns `Err` on malformed queries rather than panicking.
118pub fn execute_query(
119 language: &str,
120 source: &str,
121 query: &str,
122) -> Result<Vec<QueryCapture>, parser::ParserError> {
123 parser::execute_query_impl(language, source, query)
124}