Text-completion picker to select a project

This commit is contained in:
Dave
2026-02-16 19:44:29 +00:00
parent ffab287d16
commit 45bce740b6
7 changed files with 439 additions and 28 deletions

View File

@@ -20,6 +20,8 @@ walkdir = { workspace = true }
eventsource-stream = { workspace = true }
rust-embed = { workspace = true }
mime_guess = { workspace = true }
homedir = { workspace = true }
[dev-dependencies]
tempfile = "3"

View File

@@ -67,6 +67,25 @@ impl IoApi {
Ok(Json(entries))
}
/// List files and folders at an absolute path (not scoped to the project root).
#[oai(path = "/io/fs/list/absolute", method = "post")]
async fn list_directory_absolute(
&self,
payload: Json<FilePathPayload>,
) -> OpenApiResult<Json<Vec<io_fs::FileEntry>>> {
let entries = io_fs::list_directory_absolute(payload.0.path)
.await
.map_err(bad_request)?;
Ok(Json(entries))
}
/// Get the user's home directory.
#[oai(path = "/io/fs/home", method = "get")]
async fn get_home_directory(&self) -> OpenApiResult<Json<String>> {
let home = io_fs::get_home_directory().map_err(bad_request)?;
Ok(Json(home))
}
/// Search the currently open project for files containing the provided query string.
#[oai(path = "/io/search", method = "post")]
async fn search_files(

View File

@@ -9,6 +9,13 @@ const KEY_LAST_PROJECT: &str = "last_project_path";
const KEY_SELECTED_MODEL: &str = "selected_model";
const KEY_KNOWN_PROJECTS: &str = "known_projects";
pub fn get_home_directory() -> Result<String, String> {
let home = homedir::my_home()
.map_err(|e| format!("Failed to resolve home directory: {e}"))?
.ok_or_else(|| "Home directory not found".to_string())?;
Ok(home.to_string_lossy().to_string())
}
/// Resolves a relative path against the active project root (pure function for testing).
/// Returns error if path attempts traversal (..).
fn resolve_path_impl(root: PathBuf, relative_path: &str) -> Result<PathBuf, String> {
@@ -209,3 +216,8 @@ pub async fn list_directory(path: String, state: &SessionState) -> Result<Vec<Fi
let full_path = resolve_path(state, &path)?;
list_directory_impl(full_path).await
}
pub async fn list_directory_absolute(path: String) -> Result<Vec<FileEntry>, String> {
let full_path = PathBuf::from(path);
list_directory_impl(full_path).await
}