chore: sync current workspace changes
Desktop CI Build / Build macOS ARM64 DMG (push) Has been cancelled
Desktop CI Build / Build Windows x64 (push) Has been cancelled
Desktop CI Build / Build macOS ARM64 DMG (push) Has been cancelled
Desktop CI Build / Build Windows x64 (push) Has been cancelled
This commit is contained in:
@@ -34,6 +34,29 @@ pub enum PermissionAction {
|
||||
HardDeny,
|
||||
}
|
||||
|
||||
/// The desktop agent deliberately exposes a small, auditable tool surface.
|
||||
/// Keep this list in sync with the tools registered in `commands::agent`.
|
||||
pub const DESKTOP_ALLOWED_TOOLS: &[&str] = &[
|
||||
"Read",
|
||||
"Write",
|
||||
"Edit",
|
||||
"Glob",
|
||||
"Grep",
|
||||
"AskUserQuestion",
|
||||
"Bash",
|
||||
"Skill",
|
||||
];
|
||||
|
||||
pub fn is_desktop_tool_allowed(tool_name: &str) -> bool {
|
||||
DESKTOP_ALLOWED_TOOLS
|
||||
.iter()
|
||||
.any(|allowed| allowed.eq_ignore_ascii_case(tool_name))
|
||||
}
|
||||
|
||||
pub fn is_bash_tool(tool_name: &str) -> bool {
|
||||
tool_name.eq_ignore_ascii_case("bash")
|
||||
}
|
||||
|
||||
/// Classify a tool's risk level based on its name
|
||||
pub fn classify_tool_risk(tool_name: &str) -> RiskLevel {
|
||||
let name_lower = tool_name.to_lowercase();
|
||||
@@ -86,6 +109,12 @@ pub fn decide_permission(
|
||||
risk: RiskLevel,
|
||||
is_always_allowed: bool,
|
||||
) -> PermissionAction {
|
||||
// Host command execution is always a one-shot decision. It must never be
|
||||
// inherited from FullAccess or a remembered approval.
|
||||
if risk == RiskLevel::Execute {
|
||||
return PermissionAction::RequireApproval;
|
||||
}
|
||||
|
||||
// If tool was previously approved with "always allow", auto-allow
|
||||
if is_always_allowed {
|
||||
return PermissionAction::AutoAllow;
|
||||
@@ -102,7 +131,34 @@ pub fn decide_permission(
|
||||
(PermissionMode::AcceptEdits, RiskLevel::Write) => PermissionAction::AutoAllow,
|
||||
(PermissionMode::AcceptEdits, RiskLevel::Execute) => PermissionAction::RequireApproval,
|
||||
|
||||
// Full access: everything auto-allowed
|
||||
// Full access applies to file operations. Execute was handled above.
|
||||
(PermissionMode::FullAccess, _) => PermissionAction::AutoAllow,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn desktop_tool_allowlist_denies_unknown_capabilities() {
|
||||
assert!(is_desktop_tool_allowed("Read"));
|
||||
assert!(is_desktop_tool_allowed("skill"));
|
||||
assert!(!is_desktop_tool_allowed("WebFetch"));
|
||||
assert!(!is_desktop_tool_allowed("NotebookEdit"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bash_always_requires_one_shot_approval() {
|
||||
for mode in [
|
||||
PermissionMode::Default,
|
||||
PermissionMode::AcceptEdits,
|
||||
PermissionMode::FullAccess,
|
||||
] {
|
||||
assert_eq!(
|
||||
decide_permission(mode, RiskLevel::Execute, true),
|
||||
PermissionAction::RequireApproval
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user