lean_ctx/core/context_package/
auto_load.rs1use std::collections::HashSet;
2use std::sync::Mutex;
3
4use super::registry::LocalRegistry;
5
6static APPLIED_PACKAGES: Mutex<Option<HashSet<String>>> = Mutex::new(None);
7
8pub fn auto_load_packages(project_root: &str) -> Vec<String> {
9 let Ok(registry) = LocalRegistry::open() else {
10 return Vec::new();
11 };
12
13 let Ok(packages) = registry.auto_load_packages() else {
14 return Vec::new();
15 };
16
17 if packages.is_empty() {
18 return Vec::new();
19 }
20
21 let mut guard = APPLIED_PACKAGES
22 .lock()
23 .unwrap_or_else(std::sync::PoisonError::into_inner);
24 let applied = guard.get_or_insert_with(HashSet::new);
25
26 let mut loaded = Vec::new();
27
28 for entry in &packages {
29 let key = format!("{}@{}:{project_root}", entry.name, entry.version);
30 if applied.contains(&key) {
31 continue;
32 }
33
34 let Ok((manifest, content)) = registry.load_package(&entry.name, &entry.version) else {
35 tracing::warn!(
36 "ctxpkg auto-load: failed to load {} v{}",
37 entry.name,
38 entry.version
39 );
40 continue;
41 };
42
43 match super::loader::load_package(&manifest, &content, project_root) {
44 Ok(report) => {
45 applied.insert(key);
46 let label = format!("{} v{}", entry.name, entry.version);
47 if !report.warnings.is_empty() {
48 for w in &report.warnings {
49 tracing::warn!("ctxpkg auto-load {label}: {w}");
50 }
51 }
52 loaded.push(label);
53 }
54 Err(e) => {
55 tracing::warn!(
56 "ctxpkg auto-load: apply failed for {} v{}: {e}",
57 entry.name,
58 entry.version
59 );
60 }
61 }
62 }
63
64 loaded
65}