mirror of
https://github.com/instructkr/claw-code.git
synced 2026-04-08 09:04:49 +08:00
feat(tools): wire config.trusted_roots into WorkerCreate tool
Previously WorkerCreate passed trusted_roots directly to spawn_worker with no config-level default. Any batch script omitting the field stalled all workers at TrustRequired with no recovery path. Now run_worker_create loads RuntimeConfig from the worker CWD before spawning and merges config.trusted_roots() with per-call overrides. Per-call overrides still take effect; config provides the default. Add test: worker_create_merges_config_trusted_roots_without_per_call_override - writes .claw/settings.json with trustedRoots=[<os-temp-dir>] in a temp worktree - calls WorkerCreate with no trusted_roots field - asserts trust_auto_resolve=true (config roots matched the CWD) 81 tool tests passing, 0 failing.
This commit is contained in:
@@ -1427,9 +1427,20 @@ fn run_task_output(input: TaskIdInput) -> Result<String, String> {
|
||||
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
fn run_worker_create(input: WorkerCreateInput) -> Result<String, String> {
|
||||
// Merge config-level trusted_roots with per-call overrides.
|
||||
// Config provides the default allowlist; per-call roots add on top.
|
||||
let config_roots: Vec<String> = ConfigLoader::default_for(&input.cwd)
|
||||
.load()
|
||||
.ok()
|
||||
.map(|c| c.trusted_roots().to_vec())
|
||||
.unwrap_or_default();
|
||||
let merged_roots: Vec<String> = config_roots
|
||||
.into_iter()
|
||||
.chain(input.trusted_roots.iter().cloned())
|
||||
.collect();
|
||||
let worker = global_worker_registry().create(
|
||||
&input.cwd,
|
||||
&input.trusted_roots,
|
||||
&merged_roots,
|
||||
input.auto_recover_prompt_misdelivery,
|
||||
);
|
||||
to_pretty_json(worker)
|
||||
@@ -5506,6 +5517,43 @@ mod tests {
|
||||
assert_eq!(accepted_output["prompt_in_flight"], true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn worker_create_merges_config_trusted_roots_without_per_call_override() {
|
||||
use std::fs;
|
||||
// Write a .claw/settings.json in a temp dir with trustedRoots
|
||||
let worktree = temp_path("config-trust-worktree");
|
||||
let claw_dir = worktree.join(".claw");
|
||||
fs::create_dir_all(&claw_dir).expect("create .claw dir");
|
||||
// Use the actual OS temp dir so the worktree path matches the allowlist
|
||||
let tmp_root = std::env::temp_dir().to_str().expect("utf-8").to_string();
|
||||
let settings = format!("{{\"trustedRoots\": [\"{tmp_root}\"]}}");
|
||||
fs::write(
|
||||
claw_dir.join("settings.json"),
|
||||
settings,
|
||||
)
|
||||
.expect("write settings");
|
||||
|
||||
// WorkerCreate with no per-call trusted_roots — config should supply them
|
||||
let cwd = worktree.to_str().expect("valid utf-8").to_string();
|
||||
let created = execute_tool(
|
||||
"WorkerCreate",
|
||||
&json!({
|
||||
"cwd": cwd
|
||||
// trusted_roots intentionally omitted
|
||||
}),
|
||||
)
|
||||
.expect("WorkerCreate should succeed");
|
||||
let output: serde_json::Value = serde_json::from_str(&created).expect("json");
|
||||
|
||||
// worktree is under /tmp, so config roots auto-resolve trust
|
||||
assert_eq!(
|
||||
output["trust_auto_resolve"], true,
|
||||
"config-level trustedRoots should auto-resolve trust without per-call override"
|
||||
);
|
||||
|
||||
fs::remove_dir_all(&worktree).ok();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn worker_tools_detect_misdelivery_and_arm_prompt_replay() {
|
||||
let created = execute_tool(
|
||||
|
||||
Reference in New Issue
Block a user