fix: add --all to cargo fmt in script/test and autoformat codebase

cargo fmt without --all fails with "Failed to find targets" in
workspace repos. This was blocking every story's gates. Also ran
cargo fmt --all to fix all existing formatting issues.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
dave
2026-04-13 14:07:08 +00:00
parent ed2526ce41
commit 845b85e7a7
128 changed files with 3566 additions and 2395 deletions
+74 -44
View File
@@ -1,21 +1,21 @@
//! Slack incoming message dispatch and slash command handling.
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::collections::HashSet;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use tokio::sync::{Mutex as TokioMutex, oneshot};
use serde::{Deserialize, Serialize};
use super::format::markdown_to_slack;
use super::history::{SlackConversationHistory, save_slack_history};
use super::meta::SlackTransport;
use crate::agents::AgentPool;
use crate::chat::ChatTransport;
use crate::chat::transport::matrix::{ConversationEntry, ConversationRole, RoomConversation};
use crate::chat::util::is_permission_approval;
use crate::slog;
use crate::chat::ChatTransport;
use crate::http::context::{PermissionDecision, PermissionForward};
use super::meta::SlackTransport;
use super::history::{SlackConversationHistory, save_slack_history};
use super::format::markdown_to_slack;
use crate::slog;
// ── Slash command types ─────────────────────────────────────────────────
@@ -81,8 +81,7 @@ pub struct SlackWebhookContext {
/// Permission requests from the MCP `prompt_permission` tool arrive here.
pub perm_rx: Arc<TokioMutex<tokio::sync::mpsc::UnboundedReceiver<PermissionForward>>>,
/// Pending permission replies keyed by channel ID.
pub pending_perm_replies:
Arc<TokioMutex<HashMap<String, oneshot::Sender<PermissionDecision>>>>,
pub pending_perm_replies: Arc<TokioMutex<HashMap<String, oneshot::Sender<PermissionDecision>>>>,
/// Seconds before an unanswered permission prompt is auto-denied.
pub permission_timeout_secs: u64,
}
@@ -154,8 +153,11 @@ pub(super) async fn handle_incoming_message(
}
HtopCommand::Start { duration_secs } => {
// On Slack, htop uses native message editing for live updates.
let snapshot =
crate::chat::transport::matrix::htop::build_htop_message(&ctx.agents, 0, duration_secs);
let snapshot = crate::chat::transport::matrix::htop::build_htop_message(
&ctx.agents,
0,
duration_secs,
);
let snapshot = markdown_to_slack(&snapshot);
let msg_id = match ctx.transport.send_message(channel, &snapshot, "").await {
Ok(id) => id,
@@ -179,9 +181,7 @@ pub(super) async fn handle_incoming_message(
duration_secs,
);
let updated = markdown_to_slack(&updated);
if let Err(e) =
transport.edit_message(&ch, &msg_id, &updated, "").await
{
if let Err(e) = transport.edit_message(&ch, &msg_id, &updated, "").await {
slog!("[slack] Failed to edit htop message: {e}");
break;
}
@@ -245,7 +245,9 @@ pub(super) async fn handle_incoming_message(
) {
let response = match rmtree_cmd {
crate::chat::transport::matrix::rmtree::RmtreeCommand::Rmtree { story_number } => {
slog!("[slack] Handling rmtree command from {user} in {channel}: story {story_number}");
slog!(
"[slack] Handling rmtree command from {user} in {channel}: story {story_number}"
);
crate::chat::transport::matrix::rmtree::handle_rmtree(
&ctx.bot_name,
&story_number,
@@ -273,7 +275,9 @@ pub(super) async fn handle_incoming_message(
slog!("[slack] Handling reset command from {user} in {channel}");
{
let mut guard = ctx.history.lock().await;
let conv = guard.entry(channel.to_string()).or_insert_with(RoomConversation::default);
let conv = guard
.entry(channel.to_string())
.or_insert_with(RoomConversation::default);
conv.session_id = None;
conv.entries.clear();
save_slack_history(&ctx.project_root, &guard);
@@ -295,7 +299,9 @@ pub(super) async fn handle_incoming_message(
story_number,
agent_hint,
} => {
slog!("[slack] Handling start command from {user} in {channel}: story {story_number}");
slog!(
"[slack] Handling start command from {user} in {channel}: story {story_number}"
);
crate::chat::transport::matrix::start::handle_start(
&ctx.bot_name,
&story_number,
@@ -320,8 +326,13 @@ pub(super) async fn handle_incoming_message(
&ctx.bot_user_id,
) {
let response = match assign_cmd {
crate::chat::transport::matrix::assign::AssignCommand::Assign { story_number, model } => {
slog!("[slack] Handling assign command from {user} in {channel}: story {story_number} model {model}");
crate::chat::transport::matrix::assign::AssignCommand::Assign {
story_number,
model,
} => {
slog!(
"[slack] Handling assign command from {user} in {channel}: story {story_number} model {model}"
);
crate::chat::transport::matrix::assign::handle_assign(
&ctx.bot_name,
&story_number,
@@ -352,17 +363,15 @@ async fn handle_llm_message(
user: &str,
user_message: &str,
) {
use crate::llm::providers::claude_code::{ClaudeCodeProvider, ClaudeCodeResult};
use crate::chat::util::drain_complete_paragraphs;
use crate::llm::providers::claude_code::{ClaudeCodeProvider, ClaudeCodeResult};
use std::sync::atomic::{AtomicBool, Ordering};
use tokio::sync::watch;
// Look up existing session ID for this channel.
let resume_session_id: Option<String> = {
let guard = ctx.history.lock().await;
guard
.get(channel)
.and_then(|conv| conv.session_id.clone())
guard.get(channel).and_then(|conv| conv.session_id.clone())
};
let bot_name = &ctx.bot_name;
@@ -383,7 +392,9 @@ async fn handle_llm_message(
let post_task = tokio::spawn(async move {
while let Some(chunk) = msg_rx.recv().await {
let formatted = markdown_to_slack(&chunk);
let _ = post_transport.send_message(&post_channel, &formatted, "").await;
let _ = post_transport
.send_message(&post_channel, &formatted, "")
.await;
}
});
@@ -472,9 +483,7 @@ async fn handle_llm_message(
let last_text = messages
.iter()
.rev()
.find(|m| {
m.role == crate::llm::types::Role::Assistant && !m.content.is_empty()
})
.find(|m| m.role == crate::llm::types::Role::Assistant && !m.content.is_empty())
.map(|m| m.content.clone())
.unwrap_or_default();
if !last_text.is_empty() {
@@ -559,7 +568,10 @@ mod tests {
#[test]
fn slash_command_maps_status() {
assert_eq!(slash_command_to_bot_keyword("/huskies-status"), Some("status"));
assert_eq!(
slash_command_to_bot_keyword("/huskies-status"),
Some("status")
);
}
#[test]
@@ -600,9 +612,8 @@ mod tests {
response_type: "ephemeral",
text: "hello".to_string(),
};
let json: serde_json::Value = serde_json::from_str(
&serde_json::to_string(&resp).unwrap()
).unwrap();
let json: serde_json::Value =
serde_json::from_str(&serde_json::to_string(&resp).unwrap()).unwrap();
assert_eq!(json["response_type"], "ephemeral");
assert_eq!(json["text"], "hello");
}
@@ -642,7 +653,10 @@ mod tests {
};
let result = try_handle_command(&dispatch, &synthetic);
assert!(result.is_some(), "status slash command should produce output via registry");
assert!(
result.is_some(),
"status slash command should produce output via registry"
);
assert!(result.unwrap().contains("Pipeline Status"));
}
@@ -671,7 +685,10 @@ mod tests {
let result = try_handle_command(&dispatch, &synthetic);
assert!(result.is_some(), "show slash command should produce output");
let output = result.unwrap();
assert!(output.contains("999"), "show output should reference the story number: {output}");
assert!(
output.contains("999"),
"show output should reference the story number: {output}"
);
}
// ── rebuild command extraction ─────────────────────────────────────
@@ -704,7 +721,10 @@ mod tests {
"Huskies",
"slack-bot",
);
assert!(result.is_none(), "'status' should not be recognised as rebuild");
assert!(
result.is_none(),
"'status' should not be recognised as rebuild"
);
}
// ── reset command extraction ───────────────────────────────────────
@@ -731,21 +751,26 @@ mod tests {
#[tokio::test]
async fn reset_command_clears_slack_session() {
use crate::chat::transport::matrix::{
ConversationEntry, ConversationRole, RoomConversation,
};
use std::sync::Arc;
use tokio::sync::Mutex as TokioMutex;
use crate::chat::transport::matrix::{ConversationEntry, ConversationRole, RoomConversation};
let channel = "C01ABCDEF";
let history: SlackConversationHistory = Arc::new(TokioMutex::new({
let mut m = HashMap::new();
m.insert(channel.to_string(), RoomConversation {
session_id: Some("old-session".to_string()),
entries: vec![ConversationEntry {
role: ConversationRole::User,
sender: "U01GHIJKL".to_string(),
content: "previous message".to_string(),
}],
});
m.insert(
channel.to_string(),
RoomConversation {
session_id: Some("old-session".to_string()),
entries: vec![ConversationEntry {
role: ConversationRole::User,
sender: "U01GHIJKL".to_string(),
content: "previous message".to_string(),
}],
},
);
m
}));
@@ -755,7 +780,9 @@ mod tests {
{
let mut guard = history.lock().await;
let conv = guard.entry(channel.to_string()).or_insert_with(RoomConversation::default);
let conv = guard
.entry(channel.to_string())
.or_insert_with(RoomConversation::default);
conv.session_id = None;
conv.entries.clear();
save_slack_history(tmp.path(), &guard);
@@ -862,6 +889,9 @@ mod tests {
"Timmy",
"@timmy:home.local",
);
assert!(result.is_none(), "'status' should not be recognised as assign on Slack");
assert!(
result.is_none(),
"'status' should not be recognised as assign on Slack"
);
}
}