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:
@@ -1,22 +1,24 @@
|
||||
//! WhatsApp command handling — processes incoming WhatsApp messages as bot commands.
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::chat::transport::matrix::{ConversationEntry, ConversationRole, RoomConversation};
|
||||
use crate::chat::util::is_permission_approval;
|
||||
use crate::http::context::{PermissionDecision};
|
||||
use crate::slog;
|
||||
use super::WhatsAppWebhookContext;
|
||||
use super::format::{chunk_for_whatsapp, markdown_to_whatsapp};
|
||||
use super::history::save_whatsapp_history;
|
||||
use crate::chat::transport::matrix::{ConversationEntry, ConversationRole, RoomConversation};
|
||||
use crate::chat::util::is_permission_approval;
|
||||
use crate::http::context::PermissionDecision;
|
||||
use crate::slog;
|
||||
|
||||
/// Dispatch an incoming WhatsApp message to bot commands.
|
||||
pub(super) async fn handle_incoming_message(ctx: &WhatsAppWebhookContext, sender: &str, message: &str) {
|
||||
pub(super) async fn handle_incoming_message(
|
||||
ctx: &WhatsAppWebhookContext,
|
||||
sender: &str,
|
||||
message: &str,
|
||||
) {
|
||||
use crate::chat::commands::{CommandDispatch, try_handle_command};
|
||||
|
||||
// Allowlist check: when configured, silently ignore unauthorized senders.
|
||||
if !ctx.allowed_phones.is_empty()
|
||||
&& !ctx.allowed_phones.iter().any(|p| p == sender)
|
||||
{
|
||||
if !ctx.allowed_phones.is_empty() && !ctx.allowed_phones.iter().any(|p| p == sender) {
|
||||
slog!("[whatsapp] Ignoring message from unauthorized sender: {sender}");
|
||||
return;
|
||||
}
|
||||
@@ -173,7 +175,9 @@ pub(super) async fn handle_incoming_message(ctx: &WhatsAppWebhookContext, sender
|
||||
slog!("[whatsapp] Handling reset command from {sender}");
|
||||
{
|
||||
let mut guard = ctx.history.lock().await;
|
||||
let conv = guard.entry(sender.to_string()).or_insert_with(RoomConversation::default);
|
||||
let conv = guard
|
||||
.entry(sender.to_string())
|
||||
.or_insert_with(RoomConversation::default);
|
||||
conv.session_id = None;
|
||||
conv.entries.clear();
|
||||
save_whatsapp_history(&ctx.project_root, &guard);
|
||||
@@ -219,8 +223,13 @@ pub(super) async fn handle_incoming_message(ctx: &WhatsAppWebhookContext, sender
|
||||
&ctx.bot_user_id,
|
||||
) {
|
||||
let response = match assign_cmd {
|
||||
crate::chat::transport::matrix::assign::AssignCommand::Assign { story_number, model } => {
|
||||
slog!("[whatsapp] Handling assign command from {sender}: story {story_number} model {model}");
|
||||
crate::chat::transport::matrix::assign::AssignCommand::Assign {
|
||||
story_number,
|
||||
model,
|
||||
} => {
|
||||
slog!(
|
||||
"[whatsapp] Handling assign command from {sender}: story {story_number} model {model}"
|
||||
);
|
||||
crate::chat::transport::matrix::assign::handle_assign(
|
||||
&ctx.bot_name,
|
||||
&story_number,
|
||||
@@ -385,9 +394,7 @@ async fn handle_llm_message(ctx: &WhatsAppWebhookContext, sender: &str, user_mes
|
||||
Err(e) => {
|
||||
slog!("[whatsapp] LLM error: {e}");
|
||||
let err_msg = if let Some(url) = crate::llm::oauth::extract_login_url_from_error(&e) {
|
||||
format!(
|
||||
"Authentication required. Log in to Claude here: {url}"
|
||||
)
|
||||
format!("Authentication required. Log in to Claude here: {url}")
|
||||
} else {
|
||||
format!("Error processing your request: {e}")
|
||||
};
|
||||
@@ -434,20 +441,18 @@ async fn handle_llm_message(ctx: &WhatsAppWebhookContext, sender: &str, user_mes
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::agents::AgentPool;
|
||||
use crate::io::watcher::WatcherEvent;
|
||||
use crate::chat::transport::matrix::{ConversationEntry, ConversationRole, RoomConversation};
|
||||
use super::super::history::{MessagingWindowTracker, WhatsAppConversationHistory};
|
||||
use super::super::WhatsAppWebhookContext;
|
||||
use super::super::history::{MessagingWindowTracker, WhatsAppConversationHistory};
|
||||
use super::*;
|
||||
use crate::agents::AgentPool;
|
||||
use crate::chat::transport::matrix::{ConversationEntry, ConversationRole, RoomConversation};
|
||||
use crate::io::watcher::WatcherEvent;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::Mutex as TokioMutex;
|
||||
|
||||
/// Build a minimal WhatsAppWebhookContext for allowlist tests.
|
||||
fn make_ctx_with_allowlist(
|
||||
allowed_phones: Vec<String>,
|
||||
) -> Arc<WhatsAppWebhookContext> {
|
||||
fn make_ctx_with_allowlist(allowed_phones: Vec<String>) -> Arc<WhatsAppWebhookContext> {
|
||||
struct NullTransport;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
@@ -505,9 +510,15 @@ mod tests {
|
||||
let err = "OAuth session expired or credentials missing. Please log in: http://localhost:3001/oauth/authorize";
|
||||
let url = crate::llm::oauth::extract_login_url_from_error(err);
|
||||
assert!(url.is_some(), "should extract URL from OAuth error");
|
||||
let msg = format!("Authentication required. Log in to Claude here: {}", url.unwrap());
|
||||
let msg = format!(
|
||||
"Authentication required. Log in to Claude here: {}",
|
||||
url.unwrap()
|
||||
);
|
||||
assert!(msg.contains("http://localhost:3001/oauth/authorize"));
|
||||
assert!(!msg.contains('['), "WhatsApp message should not use Markdown link syntax");
|
||||
assert!(
|
||||
!msg.contains('['),
|
||||
"WhatsApp message should not use Markdown link syntax"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -594,7 +605,10 @@ mod tests {
|
||||
"Timmy",
|
||||
"@timmy:home.local",
|
||||
);
|
||||
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 ───────────────────────────────────────
|
||||
@@ -624,14 +638,17 @@ mod tests {
|
||||
let sender = "+15555550100";
|
||||
let history: WhatsAppConversationHistory = Arc::new(TokioMutex::new({
|
||||
let mut m = HashMap::new();
|
||||
m.insert(sender.to_string(), RoomConversation {
|
||||
session_id: Some("old-session".to_string()),
|
||||
entries: vec![ConversationEntry {
|
||||
role: ConversationRole::User,
|
||||
sender: sender.to_string(),
|
||||
content: "previous message".to_string(),
|
||||
}],
|
||||
});
|
||||
m.insert(
|
||||
sender.to_string(),
|
||||
RoomConversation {
|
||||
session_id: Some("old-session".to_string()),
|
||||
entries: vec![ConversationEntry {
|
||||
role: ConversationRole::User,
|
||||
sender: sender.to_string(),
|
||||
content: "previous message".to_string(),
|
||||
}],
|
||||
},
|
||||
);
|
||||
m
|
||||
}));
|
||||
|
||||
@@ -641,7 +658,9 @@ mod tests {
|
||||
|
||||
{
|
||||
let mut guard = history.lock().await;
|
||||
let conv = guard.entry(sender.to_string()).or_insert_with(RoomConversation::default);
|
||||
let conv = guard
|
||||
.entry(sender.to_string())
|
||||
.or_insert_with(RoomConversation::default);
|
||||
conv.session_id = None;
|
||||
conv.entries.clear();
|
||||
save_whatsapp_history(tmp.path(), &guard);
|
||||
@@ -748,7 +767,10 @@ mod tests {
|
||||
"Timmy",
|
||||
"@timmy:home.local",
|
||||
);
|
||||
assert!(result.is_none(), "'status' should not be recognised as rmtree");
|
||||
assert!(
|
||||
result.is_none(),
|
||||
"'status' should not be recognised as rmtree"
|
||||
);
|
||||
}
|
||||
|
||||
// ── assign command extraction ──────────────────────────────────────
|
||||
@@ -805,6 +827,9 @@ mod tests {
|
||||
"Timmy",
|
||||
"@timmy:home.local",
|
||||
);
|
||||
assert!(result.is_none(), "'status' should not be recognised as assign");
|
||||
assert!(
|
||||
result.is_none(),
|
||||
"'status' should not be recognised as assign"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user