From c836182448e4ad4944c0bc3c379ee5b0778d8151 Mon Sep 17 00:00:00 2001 From: greyfreedom Date: Fri, 3 Jul 2026 12:14:07 +0800 Subject: [PATCH] fix(tui): show ask rule actions in config output Add the permissions rule action to the read-only /config ask-rules table so default ask rules and explicit allow/deny rules are visible alongside tool, command, and path fields. Keep the existing missing, empty, and malformed diagnostics unchanged and cover ask, allow, deny, and stable output formatting in the config command tests. --- .../tui/src/commands/groups/config/config.rs | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/crates/tui/src/commands/groups/config/config.rs b/crates/tui/src/commands/groups/config/config.rs index b4ea421d91..3e6b295fe2 100644 --- a/crates/tui/src/commands/groups/config/config.rs +++ b/crates/tui/src/commands/groups/config/config.rs @@ -679,11 +679,12 @@ fn format_configured_ask_rules( return lines.join("\n"); } - lines.push("# | tool | command | path".to_string()); + lines.push("# | action | tool | command | path".to_string()); for (index, rule) in rules.iter().enumerate() { lines.push(format!( - "{} | {} | {} | {}", + "{} | {} | {} | {} | {}", index + 1, + format_rule_action(rule.action), format_rule_field(Some(&rule.tool)), format_rule_field(rule.command.as_deref()), format_rule_field(rule.path.as_deref()) @@ -692,6 +693,14 @@ fn format_configured_ask_rules( lines.join("\n") } +fn format_rule_action(action: codewhale_execpolicy::PermissionAction) -> &'static str { + match action { + codewhale_execpolicy::PermissionAction::Allow => "allow", + codewhale_execpolicy::PermissionAction::Ask => "ask", + codewhale_execpolicy::PermissionAction::Deny => "deny", + } +} + fn format_rule_field(value: Option<&str>) -> String { match value { Some("") => "\"\"".to_string(), @@ -2279,6 +2288,12 @@ command = "cargo test" [[rules]] tool = "edit_file" path = "src/a.rs" +action = "allow" + +[[rules]] +tool = "read_file" +path = "secrets/api_key.txt" +action = "deny" "#, ) .unwrap(); @@ -2292,10 +2307,11 @@ path = "src/a.rs" assert!(msg.contains(&format!("Permissions path: {}", permissions_path.display()))); assert!(msg.contains("File exists: yes")); assert!(msg.contains("File status: present")); - assert!(msg.contains("Rule count: 2")); - assert!(msg.contains("# | tool | command | path")); - assert!(msg.contains("1 | exec_shell | cargo test | (any)")); - assert!(msg.contains("2 | edit_file | (any) | src/a.rs")); + assert!(msg.contains("Rule count: 3")); + assert!(msg.contains("# | action | tool | command | path")); + assert!(msg.contains("1 | ask | exec_shell | cargo test | (any)")); + assert!(msg.contains("2 | allow | edit_file | (any) | src/a.rs")); + assert!(msg.contains("3 | deny | read_file | (any) | secrets/api_key.txt")); } #[test] @@ -2330,9 +2346,15 @@ tool = #[test] fn config_command_ask_rules_output_format_is_stable() { + let mut allow_rule = codewhale_config::ToolAskRule::file_path("edit_file", r"src\a.rs"); + allow_rule.action = codewhale_execpolicy::PermissionAction::Allow; + let mut deny_rule = + codewhale_config::ToolAskRule::file_path("read_file", "secrets/api_key.txt"); + deny_rule.action = codewhale_execpolicy::PermissionAction::Deny; let rules = vec![ codewhale_config::ToolAskRule::exec_shell("cargo test"), - codewhale_config::ToolAskRule::file_path("edit_file", r"src\a.rs"), + allow_rule, + deny_rule, ]; let output = format_configured_ask_rules( @@ -2348,10 +2370,11 @@ tool = Permissions path: permissions.toml\n\ File exists: yes\n\ File status: present\n\ -Rule count: 2\n\ -# | tool | command | path\n\ -1 | exec_shell | cargo test | (any)\n\ -2 | edit_file | (any) | src\\a.rs" +Rule count: 3\n\ +# | action | tool | command | path\n\ +1 | ask | exec_shell | cargo test | (any)\n\ +2 | allow | edit_file | (any) | src\\a.rs\n\ +3 | deny | read_file | (any) | secrets/api_key.txt" ); }