diff --git a/server/src/agents/pool/auto_assign/story_checks.rs b/server/src/agents/pool/auto_assign/story_checks.rs index 44b6f1f9..412ad71e 100644 --- a/server/src/agents/pool/auto_assign/story_checks.rs +++ b/server/src/agents/pool/auto_assign/story_checks.rs @@ -318,12 +318,12 @@ mod tests { ); // Set the typed CRDT register (this is the path 871's migration uses). - let written = - crate::crdt_state::set_agent("9971_story_pin_in_crdt", Some("coder-opus")); + let written = crate::crdt_state::set_agent("9971_story_pin_in_crdt", Some("coder-opus")); assert!(written, "set_agent should succeed for an existing item"); // The reader must return the CRDT register value, not None. - let agent = read_story_front_matter_agent(tmp.path(), "2_current", "9971_story_pin_in_crdt"); + let agent = + read_story_front_matter_agent(tmp.path(), "2_current", "9971_story_pin_in_crdt"); assert_eq!(agent.as_deref(), Some("coder-opus")); } } diff --git a/server/src/chat/transport/matrix/bot/permission_listener.rs b/server/src/chat/transport/matrix/bot/permission_listener.rs index 3e6bf788..f4caa971 100644 --- a/server/src/chat/transport/matrix/bot/permission_listener.rs +++ b/server/src/chat/transport/matrix/bot/permission_listener.rs @@ -36,9 +36,7 @@ pub fn spawn_permission_listener( tokio::spawn(async move { let mut perm_rx = services.perm_rx.lock().await; let target_room_str = target_room.as_str().to_string(); - slog!( - "[matrix-bot] permission listener started; forwarding requests to {target_room_str}" - ); + slog!("[matrix-bot] permission listener started; forwarding requests to {target_room_str}"); while let Some(perm_fwd) = perm_rx.recv().await { let prompt_msg = format!( @@ -131,13 +129,7 @@ mod tests { Ok("$test_event_id:example.com".to_string()) } - async fn edit_message( - &self, - _: &str, - _: &str, - _: &str, - _: &str, - ) -> Result<(), String> { + async fn edit_message(&self, _: &str, _: &str, _: &str, _: &str) -> Result<(), String> { Ok(()) } @@ -146,19 +138,14 @@ mod tests { } } - fn test_services_with_tx() -> ( - Arc, - mpsc::UnboundedSender, - ) { + fn test_services_with_tx() -> (Arc, mpsc::UnboundedSender) { let (perm_tx, perm_rx) = mpsc::unbounded_channel(); let services = Arc::new(Services { project_root: std::path::PathBuf::from("/tmp/test"), agents: Arc::new(crate::agents::AgentPool::new_test(3000)), bot_name: "Assistant".to_string(), bot_user_id: "@bot:example.com".to_string(), - ambient_rooms: Arc::new(std::sync::Mutex::new( - std::collections::HashSet::new(), - )), + ambient_rooms: Arc::new(std::sync::Mutex::new(std::collections::HashSet::new())), perm_rx: Arc::new(TokioMutex::new(perm_rx)), pending_perm_replies: Arc::new(TokioMutex::new(HashMap::new())), permission_timeout_secs: 120, diff --git a/server/src/http/mcp/mod.rs b/server/src/http/mcp/mod.rs index c993ec3a..dcc5e44a 100644 --- a/server/src/http/mcp/mod.rs +++ b/server/src/http/mcp/mod.rs @@ -61,11 +61,7 @@ pub async fn mcp_get_handler() -> Response { /// `POST /mcp` — JSON-RPC 2.0 entry point for `initialize`, `tools/list`, /// `tools/call`, and `notifications/*`. #[handler] -pub async fn mcp_post_handler( - req: &Request, - body: Body, - ctx: Data<&Arc>, -) -> Response { +pub async fn mcp_post_handler(req: &Request, body: Body, ctx: Data<&Arc>) -> Response { let content_type = req.header("content-type").unwrap_or(""); if !content_type.is_empty() && !content_type.contains("application/json") { return json_response(JsonRpcResponse::error( diff --git a/server/src/http/mcp/shell_tools/script.rs b/server/src/http/mcp/shell_tools/script.rs index c59b126d..0c4d589c 100644 --- a/server/src/http/mcp/shell_tools/script.rs +++ b/server/src/http/mcp/shell_tools/script.rs @@ -366,12 +366,8 @@ async fn run_script_tool( // When verbose, fall back to the legacy truncated output so callers // who actually want raw text still get a bounded payload. - let mut payload = build_diagnostic_response( - result.status.success(), - exit_code, - &combined, - verbose, - ); + let mut payload = + build_diagnostic_response(result.status.success(), exit_code, &combined, verbose); if verbose { payload["output"] = serde_json::json!(truncate_output(&combined, MAX_OUTPUT_LINES)); } @@ -715,7 +711,10 @@ mod tests { "last error code should be parsed" ); let summary = parsed["summary"].as_str().expect("summary string"); - assert!(summary.contains("150 error"), "summary mentions error count: {summary}"); + assert!( + summary.contains("150 error"), + "summary mentions error count: {summary}" + ); // Default response should be small even with 150 errors. assert!( result.len() < 50_000, @@ -724,9 +723,13 @@ mod tests { ); // Verbose mode: raw output is included. - let result_v = tool_run_check(&json!({"verbose": true}), &ctx).await.unwrap(); + let result_v = tool_run_check(&json!({"verbose": true}), &ctx) + .await + .unwrap(); let parsed_v: serde_json::Value = serde_json::from_str(&result_v).unwrap(); - let output = parsed_v["output"].as_str().expect("verbose includes output"); + let output = parsed_v["output"] + .as_str() + .expect("verbose includes output"); assert!(output.contains("error[E1]"), "verbose contains first line"); assert!(output.contains("error[E150]"), "verbose contains last line"); } diff --git a/server/src/service/shell/mod.rs b/server/src/service/shell/mod.rs index 37e6f332..83c28d2c 100644 --- a/server/src/service/shell/mod.rs +++ b/server/src/service/shell/mod.rs @@ -8,12 +8,12 @@ /// Side-effectful shell I/O — filesystem permission checks. pub mod io; -/// Pure command-safety checks, blocked-binary lists, and output truncation. -pub mod path_guard; /// Cargo / rustc diagnostic parser — extracts structured errors and warnings /// from raw cargo output. Used by run_check / run_build / run_lint MCP tools /// (bug 886). pub mod parse_diagnostics; +/// Pure command-safety checks, blocked-binary lists, and output truncation. +pub mod path_guard; #[allow(unused_imports)] pub use path_guard::{ diff --git a/server/src/service/shell/parse_diagnostics.rs b/server/src/service/shell/parse_diagnostics.rs index b873b875..1c7ca3a8 100644 --- a/server/src/service/shell/parse_diagnostics.rs +++ b/server/src/service/shell/parse_diagnostics.rs @@ -59,8 +59,8 @@ pub fn parse_diagnostics(output: &str) -> Vec { // Anchored to start-of-line: "error" or "warning", optional [CODE], colon, message. Regex::new(r"^(error|warning)(?:\[([A-Za-z0-9]+)\])?: (.+)$").unwrap() }); - let loc_re = LOC_RE - .get_or_init(|| Regex::new(r"^\s*-->\s+([^:\s][^:]*):(\d+)(?::\d+)?\s*$").unwrap()); + let loc_re = + LOC_RE.get_or_init(|| Regex::new(r"^\s*-->\s+([^:\s][^:]*):(\d+)(?::\d+)?\s*$").unwrap()); let lines: Vec<&str> = output.lines().collect(); let mut diagnostics = Vec::new(); @@ -155,7 +155,8 @@ mod tests { #[test] fn ignores_non_diagnostic_lines() { - let input = " Checking huskies v0.10.4\n Compiling foo v0.1.0\n Finished dev profile\n"; + let input = + " Checking huskies v0.10.4\n Compiling foo v0.1.0\n Finished dev profile\n"; assert!(parse_diagnostics(input).is_empty()); } @@ -192,8 +193,10 @@ error: could not compile `huskies` (bin \"huskies\") due to 3 previous errors; 1 assert_eq!(summary.warning_count, 2); // The 3 main compile errors must be present with file + line. - let e0061: Vec<&Diagnostic> = - diags.iter().filter(|d| d.code.as_deref() == Some("E0061")).collect(); + let e0061: Vec<&Diagnostic> = diags + .iter() + .filter(|d| d.code.as_deref() == Some("E0061")) + .collect(); assert_eq!(e0061.len(), 3); let files: Vec> = e0061.iter().map(|d| d.file.as_deref()).collect(); assert!(files.contains(&Some("server/src/agents/pool/auto_assign/merge.rs")));