Skip to main content

lean_ctx/tools/registered/
mod.rs

1pub mod ctx_agent;
2pub mod ctx_analyze;
3pub mod ctx_architecture;
4pub mod ctx_artifacts;
5pub mod ctx_benchmark;
6pub mod ctx_cache;
7pub mod ctx_call;
8pub mod ctx_callgraph;
9pub mod ctx_compile;
10pub mod ctx_compose;
11pub mod ctx_compress;
12pub mod ctx_compress_memory;
13pub mod ctx_context;
14pub mod ctx_control;
15pub mod ctx_cost;
16pub mod ctx_dedup;
17pub mod ctx_delta;
18pub mod ctx_discover;
19pub mod ctx_discover_tools;
20pub mod ctx_edit;
21pub mod ctx_execute;
22pub mod ctx_expand;
23pub mod ctx_feedback;
24pub mod ctx_fill;
25pub mod ctx_gain;
26pub mod ctx_graph;
27pub mod ctx_handoff;
28pub mod ctx_heatmap;
29pub mod ctx_impact;
30pub mod ctx_index;
31pub mod ctx_intent;
32pub mod ctx_knowledge;
33pub mod ctx_ledger;
34pub mod ctx_load_tools;
35pub mod ctx_metrics;
36pub mod ctx_multi_read;
37pub mod ctx_outline;
38pub mod ctx_overview;
39pub mod ctx_pack;
40pub mod ctx_plan;
41pub mod ctx_prefetch;
42pub mod ctx_preload;
43pub mod ctx_proof;
44pub mod ctx_provider;
45pub mod ctx_radar;
46pub mod ctx_read;
47pub mod ctx_refactor;
48pub mod ctx_response;
49pub mod ctx_retrieve;
50pub mod ctx_review;
51pub mod ctx_routes;
52pub mod ctx_search;
53pub mod ctx_semantic_search;
54pub mod ctx_session;
55pub mod ctx_share;
56pub mod ctx_shell;
57pub mod ctx_smart_read;
58pub mod ctx_smells;
59pub mod ctx_symbol;
60pub mod ctx_task;
61pub mod ctx_tree;
62pub mod ctx_verify;
63pub mod ctx_workflow;
64
65/// Resolve a relative path against session state (sync version).
66/// Replicates the core logic of `LeanCtxServer::resolve_path` without
67/// the re-rooting fallback (which needs `startup_project_root`).
68/// Must be called within `tokio::task::block_in_place`.
69pub(crate) fn resolve_path_sync(
70    session: &crate::core::session::SessionState,
71    raw: &str,
72) -> Result<String, String> {
73    let normalized = crate::core::pathutil::normalize_tool_path(raw);
74    if normalized.is_empty() || normalized == "." {
75        return Ok(normalized);
76    }
77    let p = std::path::Path::new(&normalized);
78
79    let jail_root = session
80        .project_root
81        .as_deref()
82        .or(session.shell_cwd.as_deref())
83        .unwrap_or(".")
84        .to_string();
85
86    let resolved = if p.is_absolute() || p.exists() {
87        std::path::PathBuf::from(&normalized)
88    } else if let Some(ref root) = session.project_root {
89        let joined = std::path::Path::new(root).join(&normalized);
90        if joined.exists() {
91            joined
92        } else if let Some(ref cwd) = session.shell_cwd {
93            std::path::Path::new(cwd).join(&normalized)
94        } else {
95            std::path::Path::new(&jail_root).join(&normalized)
96        }
97    } else if let Some(ref cwd) = session.shell_cwd {
98        std::path::Path::new(cwd).join(&normalized)
99    } else {
100        std::path::Path::new(&jail_root).join(&normalized)
101    };
102
103    let jail_root_path = std::path::Path::new(&jail_root);
104    let jailed = crate::core::pathjail::jail_path(&resolved, jail_root_path)?;
105    crate::core::io_boundary::check_secret_path_for_tool("resolve_path", &jailed)?;
106
107    Ok(crate::core::pathutil::normalize_tool_path(
108        &jailed.to_string_lossy().replace('\\', "/"),
109    ))
110}