feat(milestones): add POST /api/milestones endpoint and resolve collapsible_if warnings (TD-fc685b13-d9c2-4a57-ac4d-5228a71a2ec0)
This commit is contained in:
1 parent
8f924b793a
commit
d792b50343
6 files changed
+41
-25
No files matched your search
@@ -102,7 +102,7 @@ build-nvim:
|
||||
# Stage updated server binary, perform graceful shutdown, and auto-restart (skips if binary is unchanged)
|
||||
deploy-server:
|
||||
@Write-Host "Deploying Windows Server (Staged Hot-Swap)..." -ForegroundColor Cyan
|
||||
-& { $src = "target\release\mcp-memory-server.exe"; $targets = @("$env:USERPROFILE\.local\bin\mcp-memory-server.exe", "$env:USERPROFILE\.cargo\bin\mcp-memory-server.exe"); $srcHash = if (Test-Path $src) { (Get-FileHash $src -Algorithm SHA256).Hash } else { $null }; $updated = $false; foreach ($target in $targets) { $parent = Split-Path $target; if (Test-Path $parent) { if ((Test-Path $target) -and $srcHash -and ((Get-FileHash $target -Algorithm SHA256).Hash -eq $srcHash)) { Write-Host "Skipping copy to $target (identical checksum)." -ForegroundColor Yellow } else { if (Test-Path $target) { $bak = "$target.old.$([guid]::NewGuid().ToString().Substring(0,8))"; Move-Item -Force $target $bak -ErrorAction SilentlyContinue }; Copy-Item -Force $src $target; Get-ChildItem "$parent\mcp-memory-server.exe.old.*" -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue; Write-Host "Copied updated binary to $target" -ForegroundColor Green; $updated = $true } } }; if ($updated -or -not (Get-NetTCPConnection -LocalPort 3000 -State Listen -ErrorAction SilentlyContinue)) { just stop; just start } else { Write-Host "Server binary unchanged and server is running. Skipping restart." -ForegroundColor Green } }
|
||||
-& { $src = "target\release\mcp-memory-server.exe"; $targets = @("$env:USERPROFILE\.local\bin\mcp-memory-server.exe", "$env:USERPROFILE\.cargo\bin\mcp-memory-server.exe", "$env:USERPROFILE\.gemini\antigravity-cli\mcp\mcp-memory\mcp-memory.exe"); $srcHash = if (Test-Path $src) { (Get-FileHash $src -Algorithm SHA256).Hash } else { $null }; $updated = $false; foreach ($target in $targets) { $parent = Split-Path $target; if (Test-Path $parent) { if ((Test-Path $target) -and $srcHash -and ((Get-FileHash $target -Algorithm SHA256).Hash -eq $srcHash)) { Write-Host "Skipping copy to $target (identical checksum)." -ForegroundColor Yellow } else { if (Test-Path $target) { $bak = "$target.old.$([guid]::NewGuid().ToString().Substring(0,8))"; Move-Item -Force $target $bak -ErrorAction SilentlyContinue }; Copy-Item -Force $src $target; Get-ChildItem "$parent\mcp-memory-server.exe.old.*" -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue; Write-Host "Copied updated binary to $target" -ForegroundColor Green; $updated = $true } } }; if ($updated -or -not (Get-NetTCPConnection -LocalPort 3000 -State Listen -ErrorAction SilentlyContinue)) { just stop; just start } else { Write-Host "Server binary unchanged and server is running. Skipping restart." -ForegroundColor Green } }
|
||||
|
||||
# Deploy Windows-native stub binary (skips if identical checksum)
|
||||
deploy-stub-win:
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -11,13 +11,12 @@ 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() {
|
||||
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));
|
||||
}
|
||||
None
|
||||
@@ -71,17 +70,16 @@ 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(
|
||||
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));
|
||||
}
|
||||
None
|
||||
|
||||
+6
-10
@@ -56,11 +56,11 @@ 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) {
|
||||
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);
|
||||
|
||||
info!("Proactive Daemon Hooks: File modified: {:?}", path);
|
||||
@@ -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>) {
|
||||
|
||||
@@ -40,7 +40,7 @@ async fn test_stub_connection_refused() {
|
||||
.spawn()
|
||||
.expect("Failed to execute stub");
|
||||
|
||||
let res = tokio::time::timeout(Duration::from_secs(5), child.wait()).await;
|
||||
let res = tokio::time::timeout(Duration::from_secs(15), child.wait()).await;
|
||||
let elapsed = start.elapsed();
|
||||
|
||||
assert!(
|
||||
@@ -71,7 +71,7 @@ async fn test_stub_handles_eof_cleanly() {
|
||||
} // stdin dropped here
|
||||
|
||||
let start = Instant::now();
|
||||
let res = tokio::time::timeout(Duration::from_secs(5), child.wait()).await;
|
||||
let res = tokio::time::timeout(Duration::from_secs(15), child.wait()).await;
|
||||
let elapsed = start.elapsed();
|
||||
|
||||
assert!(res.is_ok(), "Stub hung after EOF! Took {elapsed:?}");
|
||||
@@ -102,7 +102,7 @@ async fn test_stub_sse_fallback_failure() {
|
||||
.spawn()
|
||||
.expect("Failed to execute stub");
|
||||
|
||||
let res = tokio::time::timeout(Duration::from_secs(5), child.wait()).await;
|
||||
let res = tokio::time::timeout(Duration::from_secs(15), child.wait()).await;
|
||||
let elapsed = start.elapsed();
|
||||
|
||||
assert!(
|
||||
|
||||
Reference in new issue
Block a user