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
+115 -109
View File
@@ -5,7 +5,7 @@ use crate::http::context::AppContext;
use crate::http::settings::get_editor_command_from_store;
use crate::slog_warn;
use crate::worktree;
use serde_json::{json, Value};
use serde_json::{Value, json};
pub(super) async fn tool_start_agent(args: &Value, ctx: &AppContext) -> Result<String, String> {
let story_id = args
@@ -72,28 +72,32 @@ pub(super) async fn tool_stop_agent(args: &Value, ctx: &AppContext) -> Result<St
.stop_agent(&project_root, story_id, agent_name)
.await?;
Ok(format!("Agent '{agent_name}' for story '{story_id}' stopped."))
Ok(format!(
"Agent '{agent_name}' for story '{story_id}' stopped."
))
}
pub(super) fn tool_list_agents(ctx: &AppContext) -> Result<String, String> {
let project_root = ctx.agents.get_project_root(&ctx.state).ok();
let agents = ctx.agents.list_agents()?;
serde_json::to_string_pretty(&json!(agents
.iter()
.filter(|a| {
project_root
.as_deref()
.map(|root| !crate::http::agents::story_is_archived(root, &a.story_id))
.unwrap_or(true)
})
.map(|a| json!({
"story_id": a.story_id,
"agent_name": a.agent_name,
"status": a.status.to_string(),
"session_id": a.session_id,
"worktree_path": a.worktree_path,
}))
.collect::<Vec<_>>()))
serde_json::to_string_pretty(&json!(
agents
.iter()
.filter(|a| {
project_root
.as_deref()
.map(|root| !crate::http::agents::story_is_archived(root, &a.story_id))
.unwrap_or(true)
})
.map(|a| json!({
"story_id": a.story_id,
"agent_name": a.agent_name,
"status": a.status.to_string(),
"session_id": a.session_id,
"worktree_path": a.worktree_path,
}))
.collect::<Vec<_>>()
))
.map_err(|e| format!("Serialization error: {e}"))
}
@@ -124,16 +128,12 @@ pub(super) async fn tool_get_agent_output(
let project_root = ctx.agents.get_project_root(&ctx.state)?;
// Collect all matching log files, oldest first.
let log_files =
agent_log::list_story_log_files(&project_root, story_id, agent_name_filter);
let log_files = agent_log::list_story_log_files(&project_root, story_id, agent_name_filter);
let mut all_lines: Vec<String> = Vec::new();
for path in &log_files {
let file_name = path
.file_name()
.and_then(|n| n.to_str())
.unwrap_or("?");
let file_name = path.file_name().and_then(|n| n.to_str()).unwrap_or("?");
all_lines.push(format!("=== {} ===", file_name.trim_end_matches(".log")));
match agent_log::read_log_as_readable_lines(path) {
Ok(lines) => all_lines.extend(lines),
@@ -156,8 +156,7 @@ pub(super) async fn tool_get_agent_output(
let now = chrono::Utc::now().to_rfc3339();
for event in &live_events {
if let Ok(event_value) = serde_json::to_value(event)
&& let Some(line) =
agent_log::format_log_entry_as_text(&now, &event_value)
&& let Some(line) = agent_log::format_log_entry_as_text(&now, &event_value)
{
all_lines.push(line);
}
@@ -201,8 +200,7 @@ pub(super) fn tool_get_agent_config(ctx: &AppContext) -> Result<String, String>
// Collect available (idle) agent names across all stages so the caller can
// see at a glance which agents are free to start (story 190).
let mut available_names: std::collections::HashSet<String> =
std::collections::HashSet::new();
let mut available_names: std::collections::HashSet<String> = std::collections::HashSet::new();
for stage in &[
PipelineStage::Coder,
PipelineStage::Qa,
@@ -214,19 +212,21 @@ pub(super) fn tool_get_agent_config(ctx: &AppContext) -> Result<String, String>
}
}
serde_json::to_string_pretty(&json!(config
.agent
.iter()
.map(|a| json!({
"name": a.name,
"role": a.role,
"model": a.model,
"allowed_tools": a.allowed_tools,
"max_turns": a.max_turns,
"max_budget_usd": a.max_budget_usd,
"available": available_names.contains(&a.name),
}))
.collect::<Vec<_>>()))
serde_json::to_string_pretty(&json!(
config
.agent
.iter()
.map(|a| json!({
"name": a.name,
"role": a.role,
"model": a.model,
"allowed_tools": a.allowed_tools,
"max_turns": a.max_turns,
"max_budget_usd": a.max_budget_usd,
"available": available_names.contains(&a.name),
}))
.collect::<Vec<_>>()
))
.map_err(|e| format!("Serialization error: {e}"))
}
@@ -254,11 +254,13 @@ pub(super) async fn tool_wait_for_agent(args: &Value, ctx: &AppContext) -> Resul
_ => None,
};
let completion = info.completion.as_ref().map(|r| json!({
"summary": r.summary,
"gates_passed": r.gates_passed,
"gate_output": r.gate_output,
}));
let completion = info.completion.as_ref().map(|r| {
json!({
"summary": r.summary,
"gates_passed": r.gates_passed,
"gate_output": r.gate_output,
})
});
serde_json::to_string_pretty(&json!({
"story_id": info.story_id,
@@ -295,13 +297,15 @@ pub(super) fn tool_list_worktrees(ctx: &AppContext) -> Result<String, String> {
let project_root = ctx.agents.get_project_root(&ctx.state)?;
let entries = worktree::list_worktrees(&project_root)?;
serde_json::to_string_pretty(&json!(entries
.iter()
.map(|e| json!({
"story_id": e.story_id,
"path": e.path.to_string_lossy(),
}))
.collect::<Vec<_>>()))
serde_json::to_string_pretty(&json!(
entries
.iter()
.map(|e| json!({
"story_id": e.story_id,
"path": e.path.to_string_lossy(),
}))
.collect::<Vec<_>>()
))
.map_err(|e| format!("Serialization error: {e}"))
}
@@ -332,7 +336,10 @@ pub(super) fn tool_get_editor_command(args: &Value, ctx: &AppContext) -> Result<
/// Run `git log <base>..HEAD --oneline` in the worktree and return the commit
/// summaries, or `None` if git is unavailable or there are no new commits.
pub(super) async fn get_worktree_commits(worktree_path: &str, base_branch: &str) -> Option<Vec<String>> {
pub(super) async fn get_worktree_commits(
worktree_path: &str,
base_branch: &str,
) -> Option<Vec<String>> {
let wt = worktree_path.to_string();
let base = base_branch.to_string();
tokio::task::spawn_blocking(move || {
@@ -382,7 +389,11 @@ mod tests {
let result = tool_get_agent_config(&ctx).unwrap();
let parsed: Vec<Value> = serde_json::from_str(&result).unwrap();
// Default config contains one agent entry with default values
assert_eq!(parsed.len(), 1, "default config should have one fallback agent");
assert_eq!(
parsed.len(),
1,
"default config should have one fallback agent"
);
assert!(parsed[0].get("name").is_some());
assert!(parsed[0].get("role").is_some());
}
@@ -401,12 +412,10 @@ mod tests {
let tmp = tempfile::tempdir().unwrap();
let ctx = test_ctx(tmp.path());
// No agent registered, no log file → returns "no log files found" message
let result = tool_get_agent_output(
&json!({"story_id": "99_nope", "agent_name": "bot"}),
&ctx,
)
.await
.unwrap();
let result =
tool_get_agent_output(&json!({"story_id": "99_nope", "agent_name": "bot"}), &ctx)
.await
.unwrap();
assert!(
result.contains("No log files found"),
"expected 'No log files found' message: {result}"
@@ -418,12 +427,9 @@ mod tests {
let tmp = tempfile::tempdir().unwrap();
let ctx = test_ctx(tmp.path());
// No agent_name provided — should succeed (no error)
let result = tool_get_agent_output(
&json!({"story_id": "99_nope"}),
&ctx,
)
.await
.unwrap();
let result = tool_get_agent_output(&json!({"story_id": "99_nope"}), &ctx)
.await
.unwrap();
assert!(result.contains("No log files found"));
}
@@ -440,13 +446,8 @@ mod tests {
.set("project_root", json!(tmp.path().to_string_lossy().as_ref()));
// Write a log file
let mut writer = AgentLogWriter::new(
tmp.path(),
"42_story_foo",
"coder-1",
"sess-test",
)
.unwrap();
let mut writer =
AgentLogWriter::new(tmp.path(), "42_story_foo", "coder-1", "sess-test").unwrap();
writer
.write_event(&AgentEvent::Output {
story_id: "42_story_foo".to_string(),
@@ -488,13 +489,8 @@ mod tests {
ctx.store
.set("project_root", json!(tmp.path().to_string_lossy().as_ref()));
let mut writer = AgentLogWriter::new(
tmp.path(),
"42_story_bar",
"coder-1",
"sess-tail",
)
.unwrap();
let mut writer =
AgentLogWriter::new(tmp.path(), "42_story_bar", "coder-1", "sess-tail").unwrap();
for i in 0..10 {
writer
.write_event(&AgentEvent::Output {
@@ -514,8 +510,14 @@ mod tests {
.unwrap();
// Should contain "line 7", "line 8", "line 9" but NOT "line 0"
assert!(result.contains("line 9"), "should contain last line: {result}");
assert!(!result.contains("line 0"), "should not contain early lines: {result}");
assert!(
result.contains("line 9"),
"should contain last line: {result}"
);
assert!(
!result.contains("line 0"),
"should not contain early lines: {result}"
);
}
#[tokio::test]
@@ -529,13 +531,8 @@ mod tests {
ctx.store
.set("project_root", json!(tmp.path().to_string_lossy().as_ref()));
let mut writer = AgentLogWriter::new(
tmp.path(),
"42_story_baz",
"coder-1",
"sess-filter",
)
.unwrap();
let mut writer =
AgentLogWriter::new(tmp.path(), "42_story_baz", "coder-1", "sess-filter").unwrap();
writer
.write_event(&AgentEvent::Output {
story_id: "42_story_baz".to_string(),
@@ -559,8 +556,14 @@ mod tests {
.await
.unwrap();
assert!(result.contains("needle"), "filter should keep matching lines: {result}");
assert!(!result.contains("haystack"), "filter should remove non-matching lines: {result}");
assert!(
result.contains("needle"),
"filter should keep matching lines: {result}"
);
assert!(
!result.contains("haystack"),
"filter should remove non-matching lines: {result}"
);
}
#[tokio::test]
@@ -697,10 +700,7 @@ stage = "coder"
fn tool_get_editor_command_no_editor_configured() {
let tmp = tempfile::tempdir().unwrap();
let ctx = test_ctx(tmp.path());
let result = tool_get_editor_command(
&json!({"worktree_path": "/some/path"}),
&ctx,
);
let result = tool_get_editor_command(&json!({"worktree_path": "/some/path"}), &ctx);
assert!(result.is_err());
assert!(result.unwrap_err().contains("No editor configured"));
}
@@ -725,17 +725,14 @@ stage = "coder"
let ctx = test_ctx(tmp.path());
ctx.store.set("editor_command", json!("code"));
let result = tool_get_editor_command(
&json!({"worktree_path": "/path/to/worktree"}),
&ctx,
)
.unwrap();
let result =
tool_get_editor_command(&json!({"worktree_path": "/path/to/worktree"}), &ctx).unwrap();
assert_eq!(result, "code /path/to/worktree");
}
#[test]
fn get_editor_command_in_tools_list() {
use super::super::{handle_tools_list};
use super::super::handle_tools_list;
let resp = handle_tools_list(Some(json!(1)));
let tools = resp.result.unwrap()["tools"].as_array().unwrap().clone();
let tool = tools.iter().find(|t| t["name"] == "get_editor_command");
@@ -769,9 +766,11 @@ stage = "coder"
async fn wait_for_agent_tool_nonexistent_agent_returns_error() {
let tmp = tempfile::tempdir().unwrap();
let ctx = test_ctx(tmp.path());
let result =
tool_wait_for_agent(&json!({"story_id": "99_nope", "agent_name": "bot", "timeout_ms": 50}), &ctx)
.await;
let result = tool_wait_for_agent(
&json!({"story_id": "99_nope", "agent_name": "bot", "timeout_ms": 50}),
&ctx,
)
.await;
// No agent registered — should error
assert!(result.is_err());
}
@@ -802,13 +801,19 @@ stage = "coder"
#[test]
fn wait_for_agent_tool_in_list() {
use super::super::{handle_tools_list};
use super::super::handle_tools_list;
let resp = handle_tools_list(Some(json!(1)));
let tools = resp.result.unwrap()["tools"].as_array().unwrap().clone();
let wait_tool = tools.iter().find(|t| t["name"] == "wait_for_agent");
assert!(wait_tool.is_some(), "wait_for_agent missing from tools list");
assert!(
wait_tool.is_some(),
"wait_for_agent missing from tools list"
);
let t = wait_tool.unwrap();
assert!(t["description"].as_str().unwrap().contains("block") || t["description"].as_str().unwrap().contains("Block"));
assert!(
t["description"].as_str().unwrap().contains("block")
|| t["description"].as_str().unwrap().contains("Block")
);
let required = t["inputSchema"]["required"].as_array().unwrap();
let req_names: Vec<&str> = required.iter().map(|v| v.as_str().unwrap()).collect();
assert!(req_names.contains(&"story_id"));
@@ -821,7 +826,8 @@ stage = "coder"
let tmp = tempfile::tempdir().unwrap();
let cov_dir = tmp.path().join(".huskies/coverage");
fs::create_dir_all(&cov_dir).unwrap();
let json_content = r#"{"data":[{"totals":{"lines":{"count":100,"covered":78,"percent":78.0}}}]}"#;
let json_content =
r#"{"data":[{"totals":{"lines":{"count":100,"covered":78,"percent":78.0}}}]}"#;
fs::write(cov_dir.join("server.json"), json_content).unwrap();
let pct = read_coverage_percent_from_json(tmp.path());