Skip to main content

code_kb_core/
lib.rs

1pub mod db;
2pub mod formatters;
3pub mod models;
4pub mod ops;
5pub mod queries;
6pub mod slicer;
7pub mod sync;
8pub mod telemetry;
9pub mod watcher;
10pub mod workspace;
11
12pub use db::{
13    Connection, DbError, ensure_fts_index, ensure_fts_index_path, open_read_only, open_read_write,
14};
15pub use formatters::{
16    format_blast_radius, format_context_slice, format_context_slices, format_fact_categories,
17    format_file_skeleton, format_find_symbol_results, format_import_summary, format_no_facts,
18    format_references, format_search_results, format_structural_facts, format_symbol_bodies,
19    format_symbol_body, no_facts_heading,
20};
21pub use models::{
22    BlastRadiusResult, ContextSlice, FileFact, ImpactedSymbol, LiteralFact, ReferenceSite,
23    SearchExplain, StructuralFact, Symbol, SymbolSearchResult, TestTarget, TypeFact,
24};
25pub use ops::{
26    OpError, SymbolSelector, blast_radius_op, blast_radius_selected_op, codebase_outline_op,
27    file_skeleton_op, get_context_slice_op, get_context_slice_selected_op,
28    get_context_slices_selected_op, get_symbol_bodies_selected_op, get_symbol_body_op,
29    get_symbol_body_selected_op, resolve_symbol_op,
30};
31pub use queries::{
32    QueryError, compute_blast_radius, compute_blast_radius_scoped,
33    compute_blast_radius_scoped_with_ids, count_file_symbols, file_sizes_for_paths,
34    find_callee_signatures, find_literals, find_literals_scoped, find_references,
35    find_references_ext, find_references_for_symbol, find_references_for_symbol_ext,
36    find_references_scoped, find_related_tests, find_structural_facts,
37    find_structural_facts_scoped, find_type_facts, fts_search_symbols_explained,
38    fts_search_symbols_scoped, get_file, get_symbol_by_id, get_symbol_by_name,
39    get_symbol_by_name_exact, get_symbol_overloads, import_sites, is_category_alias, is_test_path,
40    list_structural_fact_categories, list_structural_fact_categories_scoped, load_file_symbols,
41    load_scoped_outline_symbols, normalize_kind, qualify_members, sanitize_fts5_query,
42    search_symbols, search_symbols_scoped, suggest_file_paths, suggest_symbol_names,
43    workspace_name,
44};
45pub use slicer::{SliceError, slice_symbol, slice_symbol_body};
46pub use sync::{
47    PINNED_JULIE_VERSION, ReconcileReport, SyncError, create_index, delete_file, ensure_fresh_file,
48    ensure_index_matches_extractor, find_julie_extract_binary, installed_extractor_version,
49    reconcile_offline_edits, scan_workspace, update_file,
50};
51pub use telemetry::{
52    BugReportBundle, IndexFacts, TelemetryErrorRecord, TelemetryFilter, TelemetrySummary,
53    TimeWindow, ToolInvocation, ToolStat, format_telemetry_summary, generate_bug_report,
54    get_global_telemetry_dir, get_telemetry_summary, open_global_telemetry_db, open_telemetry_db,
55    record_tool_call, record_tool_call_conn,
56};
57pub use watcher::{WatcherError, WatcherHandle, start_watcher};
58pub use workspace::{
59    Workspace, WorkspaceError, is_hard_excluded, is_project_root, normalize_path, parse_file_uri,
60    strip_prefix_lossy, to_forward_slash,
61};
62
63/// Creates a temporary directory in a safe location, prioritizing `CARGO_TARGET_TMPDIR`,
64/// `TMPDIR`, and workspace `./target/tmp` over `/tmp` to avoid tmpfs quota limits.
65pub fn safe_tempdir() -> tempfile::TempDir {
66    if let Ok(target_tmp) = std::env::var("CARGO_TARGET_TMPDIR") {
67        let path = std::path::PathBuf::from(&target_tmp);
68        if (path.exists() || std::fs::create_dir_all(&path).is_ok())
69            && let Ok(dir) = tempfile::TempDir::new_in(&path)
70        {
71            return dir;
72        }
73    }
74    if let Ok(tmp) = std::env::var("TMPDIR") {
75        let path = std::path::PathBuf::from(tmp);
76        if (path.exists() || std::fs::create_dir_all(&path).is_ok())
77            && let Ok(dir) = tempfile::TempDir::new_in(&path)
78        {
79            return dir;
80        }
81    }
82
83    // Search ancestors of CARGO_MANIFEST_DIR or current_dir for workspace target/tmp
84    let mut search_dirs = Vec::new();
85    if let Ok(manifest_dir) = std::env::var("CARGO_MANIFEST_DIR") {
86        search_dirs.push(std::path::PathBuf::from(manifest_dir));
87    }
88    if let Ok(cwd) = std::env::current_dir() {
89        search_dirs.push(cwd);
90    }
91    for base in search_dirs {
92        let mut cur = base;
93        loop {
94            let candidate = cur.join("target/tmp");
95            if (cur.join("Cargo.toml").exists() || cur.join(".git").exists())
96                && (candidate.exists() || std::fs::create_dir_all(&candidate).is_ok())
97                && let Ok(dir) = tempfile::TempDir::new_in(&candidate)
98            {
99                return dir;
100            }
101            if !cur.pop() {
102                break;
103            }
104        }
105    }
106
107    tempfile::tempdir().expect("failed to create temporary directory")
108}