From 99b78d6ea46b110e5c239a8b742f14a2e5ff5e28 Mon Sep 17 00:00:00 2001 From: Yeachan-Heo Date: Tue, 31 Mar 2026 20:46:06 +0000 Subject: [PATCH] Polish Agent defaults and ignore crate-local agent artifacts Move the default Agent artifact store out of rust/crates/tools so repeated Agent runs stop generating noisy crate-local files, normalize explicit Agent names through the existing slug path, and ignore any crate-local .clawd-agents residue defensively. Keep the slice limited to the tools crate and preserve the existing manifest-writing behavior. Constraint: Must not touch unrelated dirty api files in this worktree Constraint: Keep the change limited to rust/crates/tools Rejected: Add a broader agent runtime or execution model | outside the final cleanup slice Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep Agent persistence defaults outside package directories so generated artifacts do not pollute crate working trees Tested: cargo test -p tools Not-tested: concurrent multi-process Agent writes to the default fallback store --- rust/crates/tools/.gitignore | 1 + rust/crates/tools/src/lib.rs | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 rust/crates/tools/.gitignore diff --git a/rust/crates/tools/.gitignore b/rust/crates/tools/.gitignore new file mode 100644 index 0000000..96da1ea --- /dev/null +++ b/rust/crates/tools/.gitignore @@ -0,0 +1 @@ +.clawd-agents/ diff --git a/rust/crates/tools/src/lib.rs b/rust/crates/tools/src/lib.rs index 7bb6179..5927e64 100644 --- a/rust/crates/tools/src/lib.rs +++ b/rust/crates/tools/src/lib.rs @@ -1143,7 +1143,9 @@ fn execute_agent(input: AgentInput) -> Result { let normalized_subagent_type = normalize_subagent_type(input.subagent_type.as_deref()); let agent_name = input .name - .clone() + .as_deref() + .map(slugify_agent_name) + .filter(|name| !name.is_empty()) .unwrap_or_else(|| slugify_agent_name(&input.description)); let created_at = iso8601_now(); @@ -1324,6 +1326,9 @@ fn agent_store_dir() -> Result { return Ok(std::path::PathBuf::from(path)); } let cwd = std::env::current_dir().map_err(|error| error.to_string())?; + if let Some(workspace_root) = cwd.ancestors().nth(2) { + return Ok(workspace_root.join(".clawd-agents")); + } Ok(cwd.join(".clawd-agents")) } @@ -2060,6 +2065,18 @@ mod tests { let normalized_output: serde_json::Value = serde_json::from_str(&normalized).expect("valid json"); assert_eq!(normalized_output["subagentType"], "Explore"); + + let named = execute_tool( + "Agent", + &json!({ + "description": "Review the branch", + "prompt": "Inspect diff.", + "name": "Ship Audit!!!" + }), + ) + .expect("Agent should normalize explicit names"); + let named_output: serde_json::Value = serde_json::from_str(&named).expect("valid json"); + assert_eq!(named_output["name"], "ship-audit"); let _ = std::fs::remove_dir_all(dir); } @@ -2166,7 +2183,7 @@ mod tests { #[test] fn powershell_runs_via_stub_shell() { - let _guard = env_lock().lock().expect("env lock"); + let _guard = env_lock().lock().unwrap_or_else(|err| err.into_inner()); let dir = std::env::temp_dir().join(format!( "clawd-pwsh-bin-{}", std::time::SystemTime::now() @@ -2220,7 +2237,7 @@ printf 'pwsh:%s' "$1" #[test] fn powershell_errors_when_shell_is_missing() { - let _guard = env_lock().lock().expect("env lock"); + let _guard = env_lock().lock().unwrap_or_else(|err| err.into_inner()); let original_path = std::env::var("PATH").unwrap_or_default(); let empty_dir = std::env::temp_dir().join(format!( "clawd-empty-bin-{}",