huskies: merge 824

This commit is contained in:
dave
2026-04-29 13:38:34 +00:00
parent b4854cf693
commit 59b626d3ba
13 changed files with 658 additions and 4 deletions
+2 -1
View File
@@ -11,7 +11,8 @@ pub(crate) use lifecycle::{
tool_list_agents, tool_start_agent, tool_stop_agent, tool_wait_for_agent,
};
pub(crate) use worktree::{
tool_create_worktree, tool_get_editor_command, tool_list_worktrees, tool_remove_worktree,
tool_cleanup_worktrees, tool_create_worktree, tool_get_editor_command, tool_list_worktrees,
tool_remove_worktree,
};
#[cfg(test)]
@@ -58,6 +58,22 @@ pub(crate) async fn tool_remove_worktree(args: &Value, ctx: &AppContext) -> Resu
Ok(format!("Worktree for story '{story_id}' removed."))
}
/// MCP tool handler for `cleanup_worktrees` — removes stale worktrees whose stories are done or archived.
pub(crate) async fn tool_cleanup_worktrees(
args: &Value,
ctx: &AppContext,
) -> Result<String, String> {
let confirm = args
.get("confirm")
.and_then(|v| v.as_bool())
.unwrap_or(false);
let project_root = ctx.services.agents.get_project_root(&ctx.state)?;
let config = crate::config::ProjectConfig::load(&project_root)?;
let report = worktree::run_cleanup(&project_root, &config, confirm).await;
Ok(worktree::format_report(&report, confirm))
}
pub(crate) fn tool_get_editor_command(args: &Value, ctx: &AppContext) -> Result<String, String> {
let worktree_path = args
.get("worktree_path")
+1
View File
@@ -43,6 +43,7 @@ pub(super) async fn handle_tools_call(
"create_worktree" => agent_tools::tool_create_worktree(&args, ctx).await,
"list_worktrees" => agent_tools::tool_list_worktrees(ctx),
"remove_worktree" => agent_tools::tool_remove_worktree(&args, ctx).await,
"cleanup_worktrees" => agent_tools::tool_cleanup_worktrees(&args, ctx).await,
// Editor tools
"get_editor_command" => agent_tools::tool_get_editor_command(&args, ctx),
// Lifecycle tools
@@ -167,6 +167,19 @@ pub(super) fn agent_tools() -> Vec<Value> {
"required": ["story_id"]
}
}),
json!({
"name": "cleanup_worktrees",
"description": "List orphaned worktrees (dry run) or remove them (confirm: true). A worktree is orphaned when its story is missing from the CRDT or is in Done/Archived stage.",
"inputSchema": {
"type": "object",
"properties": {
"confirm": {
"type": "boolean",
"description": "When true, remove all orphaned worktrees. When false (default), only list them."
}
}
}
}),
json!({
"name": "get_editor_command",
"description": "Get the open-in-editor command for a worktree. Returns a ready-to-paste shell command like 'zed /path/to/worktree'. Requires the editor preference to be configured via PUT /api/settings/editor.",
+2 -1
View File
@@ -88,7 +88,8 @@ mod tests {
assert!(names.contains(&"remove_criterion"));
assert!(names.contains(&"mesh_status"));
assert!(names.contains(&"run_check"));
assert_eq!(tools.len(), 68);
assert!(names.contains(&"cleanup_worktrees"));
assert_eq!(tools.len(), 69);
}
#[test]