huskies: merge 608_story_extract_io_and_anthropic_services

This commit is contained in:
dave
2026-04-24 15:50:26 +00:00
parent aba3120388
commit 65c896f07f
8 changed files with 617 additions and 291 deletions
+24 -25
View File
@@ -1,6 +1,6 @@
//! HTTP I/O endpoints — REST API for file and directory operations.
//! HTTP I/O endpoints — thin adapters over `service::file_io`.
use crate::http::context::{AppContext, OpenApiResult, bad_request};
use crate::io::fs as io_fs;
use crate::service::file_io::{self as svc, FileEntry};
use poem_openapi::{Object, OpenApi, Tags, payload::Json};
use serde::Deserialize;
use std::sync::Arc;
@@ -46,18 +46,18 @@ impl IoApi {
/// Read a file from the currently open project and return its contents.
#[oai(path = "/io/fs/read", method = "post")]
async fn read_file(&self, payload: Json<FilePathPayload>) -> OpenApiResult<Json<String>> {
let content = io_fs::read_file(payload.0.path, &self.ctx.state)
let content = svc::read_file(payload.0.path, &self.ctx.state)
.await
.map_err(bad_request)?;
.map_err(|e| bad_request(e.to_string()))?;
Ok(Json(content))
}
/// Write a file to the currently open project, creating parent directories if needed.
#[oai(path = "/io/fs/write", method = "post")]
async fn write_file(&self, payload: Json<WriteFilePayload>) -> OpenApiResult<Json<bool>> {
io_fs::write_file(payload.0.path, payload.0.content, &self.ctx.state)
svc::write_file(payload.0.path, payload.0.content, &self.ctx.state)
.await
.map_err(bad_request)?;
.map_err(|e| bad_request(e.to_string()))?;
Ok(Json(true))
}
@@ -66,10 +66,10 @@ impl IoApi {
async fn list_directory(
&self,
payload: Json<FilePathPayload>,
) -> OpenApiResult<Json<Vec<io_fs::FileEntry>>> {
let entries = io_fs::list_directory(payload.0.path, &self.ctx.state)
) -> OpenApiResult<Json<Vec<FileEntry>>> {
let entries = svc::list_directory(payload.0.path, &self.ctx.state)
.await
.map_err(bad_request)?;
.map_err(|e| bad_request(e.to_string()))?;
Ok(Json(entries))
}
@@ -78,10 +78,10 @@ impl IoApi {
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)
) -> OpenApiResult<Json<Vec<FileEntry>>> {
let entries = svc::list_directory_absolute(payload.0.path)
.await
.map_err(bad_request)?;
.map_err(|e| bad_request(e.to_string()))?;
Ok(Json(entries))
}
@@ -91,25 +91,25 @@ impl IoApi {
&self,
payload: Json<CreateDirectoryPayload>,
) -> OpenApiResult<Json<bool>> {
io_fs::create_directory_absolute(payload.0.path)
svc::create_directory_absolute(payload.0.path)
.await
.map_err(bad_request)?;
.map_err(|e| bad_request(e.to_string()))?;
Ok(Json(true))
}
/// 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)?;
let home = svc::get_home_directory().map_err(|e| bad_request(e.to_string()))?;
Ok(Json(home))
}
/// List all files in the project recursively, respecting .gitignore.
#[oai(path = "/io/fs/files", method = "get")]
async fn list_project_files(&self) -> OpenApiResult<Json<Vec<String>>> {
let files = io_fs::list_project_files(&self.ctx.state)
let files = svc::list_project_files(&self.ctx.state)
.await
.map_err(bad_request)?;
.map_err(|e| bad_request(e.to_string()))?;
Ok(Json(files))
}
@@ -118,10 +118,10 @@ impl IoApi {
async fn search_files(
&self,
payload: Json<SearchPayload>,
) -> OpenApiResult<Json<Vec<crate::io::search::SearchResult>>> {
let results = crate::io::search::search_files(payload.0.query, &self.ctx.state)
) -> OpenApiResult<Json<Vec<crate::service::file_io::SearchResult>>> {
let results = svc::search_files(payload.0.query, &self.ctx.state)
.await
.map_err(bad_request)?;
.map_err(|e| bad_request(e.to_string()))?;
Ok(Json(results))
}
@@ -130,11 +130,10 @@ impl IoApi {
async fn exec_shell(
&self,
payload: Json<ExecShellPayload>,
) -> OpenApiResult<Json<crate::io::shell::CommandOutput>> {
let output =
crate::io::shell::exec_shell(payload.0.command, payload.0.args, &self.ctx.state)
.await
.map_err(bad_request)?;
) -> OpenApiResult<Json<crate::service::file_io::CommandOutput>> {
let output = svc::exec_shell(payload.0.command, payload.0.args, &self.ctx.state)
.await
.map_err(|e| bad_request(e.to_string()))?;
Ok(Json(output))
}
}