feat(milestones): add POST /api/milestones endpoint and resolve collapsible_if warnings (TD-fc685b13-d9c2-4a57-ac4d-5228a71a2ec0)

This commit is contained in:
Riz Ashraf committed 2026-10-07 19:32:11 +01:00
1 parent 8f924b793a
commit d792b50343
6 files changed
+47 -31

No files matched your search

+19
View File
@@ -355,6 +355,25 @@ pub fn create_router(app_state: Arc<AppState>) -> Router {
let json = state_clone.project.milestones.read_with(|items| serde_json::to_string(items).unwrap_or_else(|_| "[]".to_string()));
([(axum::http::header::CONTENT_TYPE, "application/json")], json)
}
})
.post({
let state_clone = app_state.handler.state.clone();
move |axum::Json(payload): axum::Json<serde_json::Value>| async move {
use crate::router::McpTool;
let handler = crate::handlers::tasks::MilestonesHandler;
match handler.execute(payload, state_clone).await {
Ok(msg) => (
axum::http::StatusCode::OK,
axum::Json(serde_json::json!({ "status": "success", "message": msg })),
)
.into_response(),
Err(e) => (
axum::http::StatusCode::BAD_REQUEST,
axum::Json(serde_json::json!({ "status": "error", "message": e.to_string() })),
)
.into_response(),
}
}
}),
)
.route(
+3
View File
@@ -484,6 +484,9 @@ impl McpTool for MilestonesHandler {
}
if let Some(task_ids) = &req.task_ids {
m.task_ids = task_ids.clone();
if let Some(deliverables) = &req.deliverables {
m.deliverables = deliverables.clone();
}
}
found = true;
break;
+14 -16
View File
@@ -11,12 +11,11 @@ use std::sync::Arc;
pub fn get_native_clipboard_text() -> Option<String> {
for _ in 0..3 {
if let Ok(mut clipboard) = arboard::Clipboard::new() {
if let Ok(text) = clipboard.get_text() {
if !text.trim().is_empty() {
return Some(text);
}
}
if let Ok(mut clipboard) = arboard::Clipboard::new()
&& let Ok(text) = clipboard.get_text()
&& !text.trim().is_empty()
{
return Some(text);
}
std::thread::sleep(std::time::Duration::from_millis(20));
}
@@ -71,16 +70,15 @@ pub fn get_native_clipboard_image() -> Option<image::DynamicImage> {
return Some(img);
}
for _ in 0..3 {
if let Ok(mut clipboard) = arboard::Clipboard::new() {
if let Ok(image_data) = clipboard.get_image() {
if let Some(img) = ImageBuffer::<image::Rgba<u8>, _>::from_raw(
image_data.width as u32,
image_data.height as u32,
image_data.bytes.into_owned(),
) {
return Some(image::DynamicImage::ImageRgba8(img));
}
}
if let Ok(mut clipboard) = arboard::Clipboard::new()
&& let Ok(image_data) = clipboard.get_image()
&& let Some(img) = ImageBuffer::<image::Rgba<u8>, _>::from_raw(
image_data.width as u32,
image_data.height as u32,
image_data.bytes.into_owned(),
)
{
return Some(image::DynamicImage::ImageRgba8(img));
}
std::thread::sleep(std::time::Duration::from_millis(20));
}
+7 -11
View File
@@ -56,10 +56,10 @@ pub fn spawn_watcher(state: Arc<MemoryState>) {
for path in event.paths {
if should_review(&path) {
// 250ms debouncing window per file path
if let Some(last) = last_processed.get(&path) {
if now.duration_since(*last) < std::time::Duration::from_millis(250) {
continue;
}
if let Some(last) = last_processed.get(&path)
&& now.duration_since(*last) < std::time::Duration::from_millis(250)
{
continue;
}
last_processed.insert(path.clone(), now);
@@ -83,13 +83,9 @@ fn should_review(path: &Path) -> bool {
return false;
}
if let Some(ext) = path.extension() {
let ext_str = ext.to_string_lossy();
if ext_str == "rs" || ext_str == "md" || ext_str == "toml" || ext_str == "lua" {
return true;
}
}
false
path.extension()
.and_then(|ext| ext.to_str())
.is_some_and(|ext| matches!(ext, "rs" | "md" | "toml" | "lua"))
}
async fn trigger_autonomous_review(path: &Path, state: Arc<MemoryState>) {