huskies: merge 570_bug_merge_agent_work_should_check_if_story_is_already_done_before_attempting_merge
This commit is contained in:
@@ -15,6 +15,23 @@ pub(super) async fn tool_merge_agent_work(
|
|||||||
.and_then(|v| v.as_str())
|
.and_then(|v| v.as_str())
|
||||||
.ok_or("Missing required argument: story_id")?;
|
.ok_or("Missing required argument: story_id")?;
|
||||||
|
|
||||||
|
// Check CRDT stage before attempting merge — if already done or archived,
|
||||||
|
// return success immediately to avoid spurious error notifications.
|
||||||
|
if let Some(item) = crate::crdt_state::read_item(story_id)
|
||||||
|
&& (item.stage == "5_done" || item.stage == "6_archived")
|
||||||
|
{
|
||||||
|
return serde_json::to_string_pretty(&json!({
|
||||||
|
"story_id": story_id,
|
||||||
|
"status": "completed",
|
||||||
|
"success": true,
|
||||||
|
"message": format!(
|
||||||
|
"Story '{}' is already in '{}' — no merge needed.",
|
||||||
|
story_id, item.stage
|
||||||
|
),
|
||||||
|
}))
|
||||||
|
.map_err(|e| format!("Serialization error: {e}"));
|
||||||
|
}
|
||||||
|
|
||||||
let project_root = ctx.agents.get_project_root(&ctx.state)?;
|
let project_root = ctx.agents.get_project_root(&ctx.state)?;
|
||||||
ctx.agents.start_merge_agent_work(&project_root, story_id)?;
|
ctx.agents.start_merge_agent_work(&project_root, story_id)?;
|
||||||
|
|
||||||
@@ -258,6 +275,60 @@ mod tests {
|
|||||||
assert!(result.unwrap_err().contains("story_id"));
|
assert!(result.unwrap_err().contains("story_id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn tool_merge_agent_work_already_done_returns_success() {
|
||||||
|
crate::crdt_state::init_for_test();
|
||||||
|
crate::crdt_state::write_item(
|
||||||
|
"99_story_already_done",
|
||||||
|
"5_done",
|
||||||
|
Some("Already done story"),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let ctx = test_ctx(tmp.path());
|
||||||
|
let result =
|
||||||
|
tool_merge_agent_work(&json!({"story_id": "99_story_already_done"}), &ctx).await;
|
||||||
|
assert!(result.is_ok(), "expected Ok, got: {result:?}");
|
||||||
|
let body = result.unwrap();
|
||||||
|
let v: serde_json::Value = serde_json::from_str(&body).unwrap();
|
||||||
|
assert_eq!(v["status"], "completed");
|
||||||
|
assert_eq!(v["success"], true);
|
||||||
|
assert!(v["message"].as_str().unwrap().contains("5_done"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn tool_merge_agent_work_already_archived_returns_success() {
|
||||||
|
crate::crdt_state::init_for_test();
|
||||||
|
crate::crdt_state::write_item(
|
||||||
|
"98_story_already_archived",
|
||||||
|
"6_archived",
|
||||||
|
Some("Already archived story"),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let ctx = test_ctx(tmp.path());
|
||||||
|
let result =
|
||||||
|
tool_merge_agent_work(&json!({"story_id": "98_story_already_archived"}), &ctx).await;
|
||||||
|
assert!(result.is_ok(), "expected Ok, got: {result:?}");
|
||||||
|
let body = result.unwrap();
|
||||||
|
let v: serde_json::Value = serde_json::from_str(&body).unwrap();
|
||||||
|
assert_eq!(v["status"], "completed");
|
||||||
|
assert_eq!(v["success"], true);
|
||||||
|
assert!(v["message"].as_str().unwrap().contains("6_archived"));
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn tool_move_story_to_merge_missing_story_id() {
|
async fn tool_move_story_to_merge_missing_story_id() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user