chore: fix formatting and clippy lints

This commit is contained in:
Riz Ashraf committed 2026-10-08 23:01:38 +01:00
1 parent 8952bd5399
commit 9d9e959744
35 files changed
+1091 -582

No files matched your search

+134 -103
View File
@@ -110,11 +110,10 @@ impl McpTool for SearchErrorFixesHandler {
} else if st_lower.contains(&sol_lower) || sol_lower.contains(&st_lower) {
score += 0.5;
}
if let Some(emb) = &f.embedding {
if !query_emb.is_empty() {
if let Some(emb) = &f.embedding
&& !query_emb.is_empty() {
score += crate::embedding::cosine_similarity(&query_emb, emb);
}
}
(f, score)
})
.filter(|(_, score)| *score > 0.1)
@@ -198,11 +197,10 @@ impl McpTool for LogCodeChangeHandler {
if let Some(range) = &req.line_range {
description = format!("{} [Line Range: {}]", description, range);
}
if let Some(symbols) = &req.symbol_references {
if !symbols.is_empty() {
if let Some(symbols) = &req.symbol_references
&& !symbols.is_empty() {
description = format!("{} [Symbols: {}]", description, symbols.join(", "));
}
}
if state.ollama.is_available().await {
let prompt = format!(
@@ -323,13 +321,14 @@ impl McpTool for QueryRecentChangesHandler {
}
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: QueryRecentChangesTool = serde_json::from_value(args).unwrap_or(QueryRecentChangesTool {
namespace: None,
repo_name: None,
vcs_type: None,
limit: None,
offset: None,
});
let req: QueryRecentChangesTool =
serde_json::from_value(args).unwrap_or(QueryRecentChangesTool {
namespace: None,
repo_name: None,
vcs_type: None,
limit: None,
offset: None,
});
let limit = req.limit.unwrap_or(50);
let offset = req.offset.unwrap_or(0);
let data = state.code.ledger.read_with(|l| {
@@ -337,25 +336,22 @@ impl McpTool for QueryRecentChangesHandler {
.iter()
.rev()
.filter(|c| {
if let Some(ns) = &req.namespace {
if !c.namespace.eq_ignore_ascii_case(ns) {
if let Some(ns) = &req.namespace
&& !c.namespace.eq_ignore_ascii_case(ns) {
return false;
}
}
if let Some(repo) = &req.repo_name {
if c.repo_name
if let Some(repo) = &req.repo_name
&& c.repo_name
.as_ref()
.map(|rn| !rn.eq_ignore_ascii_case(repo))
.unwrap_or(true)
{
return false;
}
}
if let Some(vcs) = &req.vcs_type {
if !c.effective_vcs().eq_ignore_ascii_case(vcs) {
if let Some(vcs) = &req.vcs_type
&& !c.effective_vcs().eq_ignore_ascii_case(vcs) {
return false;
}
}
true
})
.skip(offset)
@@ -386,7 +382,7 @@ impl McpTool for DecisionsHandler {
let req: DecisionsTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let ns = req
.namespace
.unwrap_or_else(|| crate::models::default_namespace());
.unwrap_or_else(crate::models::default_namespace);
match req.action {
DecisionAction::Log => {
let title = req.title.ok_or_else(|| {
@@ -464,14 +460,14 @@ impl McpTool for DecisionsHandler {
state.code.adrs.modify(|adrs| {
let target_pos = adrs.iter().position(|a| a.id.eq_ignore_ascii_case(&id));
if let Some(pos) = target_pos {
if let Some(superseded_id) = &req.supersedes {
if let Some(s_pos) = adrs.iter().position(|a| a.id.eq_ignore_ascii_case(superseded_id)) {
if s_pos != pos {
if let Some(superseded_id) = &req.supersedes
&& let Some(s_pos) = adrs
.iter()
.position(|a| a.id.eq_ignore_ascii_case(superseded_id))
&& s_pos != pos {
adrs[s_pos].status = "superseded".to_string();
adrs_to_index.push(adrs[s_pos].clone());
}
}
}
let a = &mut adrs[pos];
if let Some(t) = req.title {
@@ -488,7 +484,9 @@ impl McpTool for DecisionsHandler {
}
if let Some(s) = req.status {
let s_lower = s.to_ascii_lowercase();
if (s_lower == "implemented" || s_lower == "resolved") && a.resolved_at.is_none() {
if (s_lower == "implemented" || s_lower == "resolved")
&& a.resolved_at.is_none()
{
a.resolved_at = Some(crate::handlers::utils::now_secs());
} else if s_lower != "implemented" && s_lower != "resolved" {
a.resolved_at = None;
@@ -535,11 +533,15 @@ impl McpTool for DecisionsHandler {
&format!("Updated {}: {}", adr.id, adr.title),
Some(&adr.status),
);
Ok(format!("Updated decision {}: {} (status: {})", adr.id, adr.title, adr.status))
} else {
Err(crate::error::AppError::Internal(
format!("Decision with id '{}' not found", id),
Ok(format!(
"Updated decision {}: {} (status: {})",
adr.id, adr.title, adr.status
))
} else {
Err(crate::error::AppError::Internal(format!(
"Decision with id '{}' not found",
id
)))
}
}
DecisionAction::Query => {
@@ -554,9 +556,17 @@ impl McpTool for DecisionsHandler {
}
if let Some(q) = &req.query {
crate::handlers::utils::contains_ignore_ascii_case(&a.title, q)
|| crate::handlers::utils::contains_ignore_ascii_case(&a.context, q)
|| crate::handlers::utils::contains_ignore_ascii_case(&a.decision, q)
|| crate::handlers::utils::contains_ignore_ascii_case(&a.consequence, q)
|| crate::handlers::utils::contains_ignore_ascii_case(
&a.context, q,
)
|| crate::handlers::utils::contains_ignore_ascii_case(
&a.decision,
q,
)
|| crate::handlers::utils::contains_ignore_ascii_case(
&a.consequence,
q,
)
} else {
true
}
@@ -632,17 +642,14 @@ impl McpTool for TechDebtHandler {
let req: TechDebtTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let ns = req
.namespace
.unwrap_or_else(|| crate::models::default_namespace());
.unwrap_or_else(crate::models::default_namespace);
match req.action {
TechDebtAction::Log => {
let desc = req.description.or(req.title).ok_or_else(|| {
crate::error::AppError::Internal("Missing required parameter 'description' for action 'log'. Next step: Provide tech debt 'description' in request and retry.".to_string())
})?;
let ideal = req.ideal_solution.unwrap_or_default();
let text_to_embed = format!(
"Description: {}\nIdeal Solution: {}",
desc, ideal
);
let text_to_embed = format!("Description: {}\nIdeal Solution: {}", desc, ideal);
let embedding = crate::embedding::generate_embedding_async(text_to_embed)
.await
.ok();
@@ -665,18 +672,21 @@ impl McpTool for TechDebtHandler {
effort_estimate: req.effort_estimate,
});
if debts.len() > 300 {
let severity_rank = |sev: Option<&str>| match sev.unwrap_or("").to_lowercase().as_str() {
"critical" => 4,
"high" => 3,
"medium" => 2,
"low" => 1,
_ => 1,
};
if let Some((idx_to_remove, _)) = debts.iter().enumerate().min_by_key(|(_, d)| {
let status_score = if d.is_resolved { 0 } else { 10 };
let sev_score = severity_rank(d.severity.as_deref());
(status_score + sev_score, d.created_at)
}) {
let severity_rank =
|sev: Option<&str>| match sev.unwrap_or("").to_lowercase().as_str() {
"critical" => 4,
"high" => 3,
"medium" => 2,
"low" => 1,
_ => 1,
};
if let Some((idx_to_remove, _)) =
debts.iter().enumerate().min_by_key(|(_, d)| {
let status_score = if d.is_resolved { 0 } else { 10 };
let sev_score = severity_rank(d.severity.as_deref());
(status_score + sev_score, d.created_at)
})
{
debts.remove(idx_to_remove);
}
}
@@ -712,9 +722,7 @@ impl McpTool for TechDebtHandler {
let data = state.code.tech_debts.read_with(|debts| {
let filtered: Vec<_> = debts
.iter()
.filter(|d| {
d.namespace == ns && (inc || !d.is_resolved)
})
.filter(|d| d.namespace == ns && (inc || !d.is_resolved))
.map(|d| match level {
"compact" => serde_json::json!({
"id": d.id,
@@ -811,7 +819,8 @@ impl McpTool for OmniSearchHandler {
let mut ranked_items: Vec<_> = rrf_scores.into_values().collect();
ranked_items.sort_by(|a, b| b.0.total_cmp(&a.0));
let matches: Vec<crate::search::SearchResult> = ranked_items.into_iter().map(|(_, item)| item).collect();
let matches: Vec<crate::search::SearchResult> =
ranked_items.into_iter().map(|(_, item)| item).collect();
let kg_json = state.read_graph(|full| {
let mut kg_results = serde_json::Map::new();
@@ -1263,25 +1272,21 @@ impl McpTool for ManageCheckpointHandler {
)));
}
if let Ok(graph_content) = std::fs::read_to_string(target_dir.join("graph.json")) {
if let Ok(graph) = serde_json::from_str(&graph_content) {
if let Ok(graph_content) = std::fs::read_to_string(target_dir.join("graph.json"))
&& let Ok(graph) = serde_json::from_str(&graph_content) {
state.graph.modify(|g| *g = graph);
}
}
if let Ok(tasks_content) = std::fs::read_to_string(target_dir.join("tasks.json")) {
if let Ok(tasks) = serde_json::from_str(&tasks_content) {
if let Ok(tasks_content) = std::fs::read_to_string(target_dir.join("tasks.json"))
&& let Ok(tasks) = serde_json::from_str(&tasks_content) {
state.project.tasks.modify(|t| *t = tasks);
}
}
if let Ok(debts_content) =
std::fs::read_to_string(target_dir.join("tech_debts.json"))
{
if let Ok(debts) = serde_json::from_str(&debts_content) {
&& let Ok(debts) = serde_json::from_str(&debts_content) {
state.code.tech_debts.modify(|d| *d = debts);
}
}
Ok(format!("Checkpoint '{}' restored successfully.", name))
}
@@ -1290,11 +1295,10 @@ impl McpTool for ManageCheckpointHandler {
let checkpoints_dir = state.base_dir.join("checkpoints");
if let Ok(entries) = std::fs::read_dir(&checkpoints_dir) {
for entry in entries.flatten() {
if entry.path().is_dir() {
if let Some(n) = entry.file_name().to_str() {
if entry.path().is_dir()
&& let Some(n) = entry.file_name().to_str() {
list.push(serde_json::json!({"type": "checkpoint", "name": n}));
}
}
}
}
let snaps = state.project.snapshots.read_with(|snaps| snaps.clone());
@@ -1461,13 +1465,11 @@ impl McpTool for GetNextActionableTasksHandler {
continue;
}
if let Some(branch) = &req.git_branch {
if let Some(tb) = &task.git_branch {
if tb != branch {
if let Some(branch) = &req.git_branch
&& let Some(tb) = &task.git_branch
&& tb != branch {
continue;
}
}
}
let unblocked = task.dependencies.is_empty()
|| task.dependencies.iter().all(|d| completed_ids.contains(d));
@@ -1509,7 +1511,9 @@ impl McpTool for HypothesesHandler {
match req.action {
HypothesisAction::Log => {
let hyp_text = req.hypothesis.ok_or_else(|| {
crate::error::AppError::Internal("Missing required 'hypothesis' for action 'log'".to_string())
crate::error::AppError::Internal(
"Missing required 'hypothesis' for action 'log'".to_string(),
)
})?;
let hyp_id = format!(
"HYP-{}",
@@ -1536,17 +1540,16 @@ impl McpTool for HypothesesHandler {
let filtered: Vec<_> = hypotheses
.into_iter()
.filter(|h| {
if let Some(tid) = &req.task_id {
if h.task_id.as_ref() != Some(tid) {
if let Some(tid) = &req.task_id
&& h.task_id.as_ref() != Some(tid) {
return false;
}
}
if let Some(q) = &req.query {
let lq = q.to_lowercase();
return h.hypothesis.to_lowercase().contains(&lq)
|| h.evidence
.as_ref()
.map_or(false, |e| e.to_lowercase().contains(&lq));
.is_some_and(|e| e.to_lowercase().contains(&lq));
}
true
})
@@ -1656,13 +1659,19 @@ impl McpTool for AgentSignalsHandler {
match req.action {
AgentSignalAction::Broadcast => {
let sender = req.sender.ok_or_else(|| {
crate::error::AppError::Internal("Missing required 'sender' for action 'broadcast'".to_string())
crate::error::AppError::Internal(
"Missing required 'sender' for action 'broadcast'".to_string(),
)
})?;
let signal_type = req.signal_type.ok_or_else(|| {
crate::error::AppError::Internal("Missing required 'signal_type' for action 'broadcast'".to_string())
crate::error::AppError::Internal(
"Missing required 'signal_type' for action 'broadcast'".to_string(),
)
})?;
let payload = req.payload.ok_or_else(|| {
crate::error::AppError::Internal("Missing required 'payload' for action 'broadcast'".to_string())
crate::error::AppError::Internal(
"Missing required 'payload' for action 'broadcast'".to_string(),
)
})?;
let timestamp = std::time::SystemTime::now()
@@ -1715,25 +1724,21 @@ impl McpTool for AgentSignalsHandler {
signals
.iter()
.filter(|s| {
if let Some(ttl) = s.ttl_seconds {
if now > s.timestamp + ttl {
if let Some(ttl) = s.ttl_seconds
&& now > s.timestamp + ttl {
return false;
}
}
if let Some(sender) = &req.sender {
if s.sender.to_lowercase() != sender.to_lowercase() {
if let Some(sender) = &req.sender
&& s.sender.to_lowercase() != sender.to_lowercase() {
return false;
}
}
if let Some(st) = &req.signal_type {
if s.signal_type.to_lowercase() != st.to_lowercase() {
if let Some(st) = &req.signal_type
&& s.signal_type.to_lowercase() != st.to_lowercase() {
return false;
}
}
true
})
.cloned()
.take(req.limit.unwrap_or(20))
.take(req.limit.unwrap_or(20)).cloned()
.collect::<Vec<_>>()
});
@@ -2110,7 +2115,10 @@ mod tests {
assert!(q_dec_res.contains("Fast async API routing"));
let q_by_consequence = handler_dec
.execute(serde_json::json!({"action": "query", "query": "Fast async"}), state.clone())
.execute(
serde_json::json!({"action": "query", "query": "Fast async"}),
state.clone(),
)
.await
.unwrap();
assert!(q_by_consequence.contains("Use Axum"));
@@ -2133,7 +2141,10 @@ mod tests {
assert!(update_res.contains("implemented"));
let q_after_update = handler_dec
.execute(serde_json::json!({"action": "query", "include_body": false}), state.clone())
.execute(
serde_json::json!({"action": "query", "include_body": false}),
state.clone(),
)
.await
.unwrap();
assert!(q_after_update.contains("implemented"));
@@ -2143,7 +2154,10 @@ mod tests {
assert!(q_after_update.contains("resolved_at"));
let del_dec_res = handler_dec
.execute(serde_json::json!({"action": "delete", "id": "ADR-0001"}), state.clone())
.execute(
serde_json::json!({"action": "delete", "id": "ADR-0001"}),
state.clone(),
)
.await;
assert!(del_dec_res.is_ok());
@@ -2163,14 +2177,20 @@ mod tests {
assert!(td_res.contains("Tech debt logged"));
let list_td_res = handler_td
.execute(serde_json::json!({"action": "list", "include_resolved": true}), state.clone())
.execute(
serde_json::json!({"action": "list", "include_resolved": true}),
state.clone(),
)
.await
.unwrap();
assert!(list_td_res.contains("Replace unwraps"));
let debt_id = state.code.tech_debts.read_with(|debts| debts[0].id.clone());
let res_td_res = handler_td
.execute(serde_json::json!({"action": "resolve", "id": debt_id}), state.clone())
.execute(
serde_json::json!({"action": "resolve", "id": debt_id}),
state.clone(),
)
.await;
assert!(res_td_res.is_ok());
@@ -2394,7 +2414,10 @@ mod tests {
)
.await
.unwrap();
assert!(rest_state_res.contains("restored successfully") || rest_state_res.contains("restored memory state from snapshot"));
assert!(
rest_state_res.contains("restored successfully")
|| rest_state_res.contains("restored memory state from snapshot")
);
let mg_list = mg_chk
.execute(serde_json::json!({"action": "list"}), state.clone())
@@ -2607,7 +2630,10 @@ mod tests {
// DeleteDecision non-existent
let del_dec_err = handler_dec
.execute(serde_json::json!({"action": "delete", "id": "ADR-9999"}), state.clone())
.execute(
serde_json::json!({"action": "delete", "id": "ADR-9999"}),
state.clone(),
)
.await;
assert!(del_dec_err.is_err());
@@ -2882,9 +2908,14 @@ mod tests {
state.code.tech_debts.read_with(|debts| {
assert_eq!(debts.len(), 300);
assert!(debts.iter().any(|d| d.id == "critical-debt"), "Critical unresolved debt must be retained");
assert!(!debts.iter().any(|d| d.id == "resolved-debt"), "Resolved debt should have been evicted first");
assert!(
debts.iter().any(|d| d.id == "critical-debt"),
"Critical unresolved debt must be retained"
);
assert!(
!debts.iter().any(|d| d.id == "resolved-debt"),
"Resolved debt should have been evicted first"
);
});
}
}