feat(mcp): implement Prompts capability, Resources, and clean up daemon architecture

This commit is contained in:
Riz Ashraf committed 2026-09-22 21:41:17 +01:00
1 parent 9b9b403ef2
commit 251757f8fc
29 files changed
+1276 -182

No files matched your search

+124
View File
@@ -508,3 +508,127 @@ impl McpTool for GetProjectHealthHandler {
}
use crate::handlers::utils::*;
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
use serde_json::json;
#[tokio::test]
async fn test_log_error_fix() {
let dir = tempdir().unwrap();
let state = Arc::new(MemoryState::new(dir.path().to_str().unwrap()));
let handler = LogErrorFixHandler;
let args = json!({
"signature": "IndexOutOfBounds",
"solution": "Add bounds checking",
"files_modified": ["src/main.rs"],
"git_commit": "abcdef",
"git_branch": "main"
});
let res = handler.execute(args, state.clone()).await.unwrap();
assert!(res.contains("Error fix logged"));
}
#[tokio::test]
async fn test_project_health() {
let dir = tempdir().unwrap();
let state = Arc::new(MemoryState::new(dir.path().to_str().unwrap()));
let handler = GetProjectHealthHandler;
let args = json!({"namespace": "global"});
let res = handler.execute(args, state.clone()).await.unwrap();
assert!(res.contains("unresolved_tech_debt"));
}
#[tokio::test]
async fn test_log_decision_and_tech_debt() {
let dir = tempdir().unwrap();
let state = Arc::new(MemoryState::new(dir.path().to_str().unwrap()));
let decision_handler = LogDecisionHandler;
let args_dec = json!({
"title": "Architecture",
"context": "Needs DB",
"decision": "Use SQLite",
"consequence": "Simple",
});
let res1 = decision_handler.execute(args_dec, state.clone()).await.unwrap();
assert_eq!(res1, "Decision logged as ADR-0001");
let debt_handler = LogTechDebtHandler;
let args_debt = json!({
"title": "Hardcoded path",
"description": "Hardcoded path",
"location": "main.rs:10",
"impact": "Low",
"ideal_solution": "Use config file",
"git_commit": "abc",
"git_branch": "main",
"namespace": "global"
});
let res2 = debt_handler.execute(args_debt, state.clone()).await.unwrap();
assert_eq!(res2, "Tech debt logged");
let list_debt = ListTechDebtHandler;
let res3 = list_debt.execute(json!({"namespace": "global", "include_resolved": false}), state.clone()).await.unwrap();
assert!(res3.contains("Hardcoded path"));
let pref_handler = LearnPreferenceHandler;
let args_pref = json!({
"key": "formatting",
"value": "use spaces",
});
let res4 = pref_handler.execute(args_pref, state.clone()).await.unwrap();
assert_eq!(res4, "Preference learned");
let read_pref = ReadPreferencesHandler;
let res5 = read_pref.execute(json!({}), state.clone()).await.unwrap();
assert!(res5.contains("use spaces"));
}
#[tokio::test]
async fn test_advanced_meta_operations() {
let dir = tempfile::tempdir().unwrap();
let state = Arc::new(MemoryState::new(dir.path().to_str().unwrap()));
let code_handler = LogCodeChangeHandler;
let args_code = json!({
"filePath": "main.rs",
"description": "refactor",
"git_commit": "def",
"git_branch": "main"
});
code_handler.execute(args_code, state.clone()).await.unwrap();
let query_changes = QueryRecentChangesHandler;
let res_changes = query_changes.execute(json!({}), state.clone()).await.unwrap();
assert!(res_changes.contains("main.rs"));
let debt_handler = LogTechDebtHandler;
let args_debt = json!({
"title": "Debt 1",
"description": "Needs refactor",
"location": "main.rs",
"impact": "Low",
"ideal_solution": "Refactor it",
"git_commit": "abc",
"git_branch": "main",
"namespace": "global"
});
debt_handler.execute(args_debt, state.clone()).await.unwrap();
// resolve it
let list_debt = ListTechDebtHandler;
let debt_list = list_debt.execute(json!({"namespace": "global", "include_resolved": false}), state.clone()).await.unwrap();
let uuid_start = debt_list.find("id\":\"").unwrap() + 5;
let uuid = &debt_list[uuid_start..uuid_start+36];
let resolve_debt = ResolveTechDebtHandler;
resolve_debt.execute(json!({"id": uuid}), state.clone()).await.unwrap();
}
}