Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0f29f09
Tool permissions settings UI improvements
rtfeldman Feb 9, 2026
f80ee0a
Remove redundant heading and description from tool permissions list page
rtfeldman Feb 9, 2026
df6905e
Replace hardcoded security regex banner with friendly inline-markdown…
rtfeldman Feb 9, 2026
33389cb
Update hardcoded rules description and make text white
rtfeldman Feb 9, 2026
2af6317
Fix panic: remove overlapping highlight range in StyledText
rtfeldman Feb 9, 2026
2eea0f7
Fix white text: use with_highlights for deferred style resolution
rtfeldman Feb 9, 2026
4ae7f38
Tool permissions schema redesign
rtfeldman Feb 9, 2026
e5eb8e1
Merge remote-tracking branch 'origin/main' into pr/tool-permissions-s…
rtfeldman Feb 10, 2026
e2dc547
Merge tool permissions documentation from tool-permission-docs branch
rtfeldman Feb 10, 2026
4cb7896
Autofix
zed-zippy[bot] Feb 10, 2026
c114d4f
Port missing improvements from always-allow-revision branch
rtfeldman Feb 10, 2026
00298d3
Migrate always_allow_tool_actions to agent_servers default_mode for C…
rtfeldman Feb 10, 2026
57f5b7d
Clarify tool permission docs
rtfeldman Feb 10, 2026
b2abeae
Autofix
zed-zippy[bot] Feb 10, 2026
6b5f551
Avoid panic in permission pattern selection
rtfeldman Feb 10, 2026
e6d2021
Document versioned tool approval settings
rtfeldman Feb 10, 2026
5af5ca5
Fix pattern consensus selection
rtfeldman Feb 10, 2026
def7c81
Harden tool permission migration
rtfeldman Feb 10, 2026
f611595
Remove case labels from migrator comments
rtfeldman Feb 10, 2026
8969a68
Avoid index access for single input
rtfeldman Feb 10, 2026
cf72cb3
Use constant for always_allow_tool_actions
rtfeldman Feb 10, 2026
1ad1b6f
Simplify tool_permissions migration map
rtfeldman Feb 10, 2026
b19b094
Use constants for migration keys
rtfeldman Feb 10, 2026
2b54a9e
Simplify tool_permissions migration logic
rtfeldman Feb 10, 2026
083294a
Merge remote-tracking branch 'origin/main' into pr/tool-permissions-s…
rtfeldman Feb 10, 2026
a178a96
Update migration tests to not expect agent_servers changes
rtfeldman Feb 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 22 additions & 13 deletions assets/settings/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -958,28 +958,37 @@
// "temperature": 1.0
// }
],
// When enabled, the agent can run tool actions without asking for your confirmation.
// This setting takes precedence over `always_confirm` patterns and `default_mode` settings,
// but `always_deny` patterns still block actions for security.
// Permission rules for tool actions.
//
// Note: This setting has no effect on external agents that support permission modes, such as Claude Code.
// You can set `agent_servers.claude.default_mode` to `bypassPermissions` to skip all permission requests.
"always_allow_tool_actions": false,
// Per-tool permission rules for granular control over tool actions.
// This setting only applies to the native Zed agent.
// The "default" setting applies when no tool-specific rules match.
// For external agents that define their own permission modes,
// "deny" and "confirm" still take precedence — the external agent's
// permission system is only used when Zed would allow the action.
//
// Per-tool regex patterns ("tools" below) match against tool input text
// (commands, paths, URLs, etc.). For `copy_path` and `move_path`,
// patterns are matched independently against each path (source and
// destination).
"tool_permissions": {
// Here are some examples of tool-specific permissions.
// Global default permission when no tool-specific rules match.
// "allow" - Auto-approve without prompting
// "deny" - Auto-reject
// "confirm" - Always prompt (default)
"default": "confirm",
// Per-tool permission rules. Regex patterns match against tool input text.
// The per-tool "default" also applies to MCP tools.
// Each tool can have its own default and regex patterns.
"tools": {
// "terminal": {
// "default_mode": "confirm",
// "default": "confirm",
// "always_confirm": [
// // Destructive git operations
// { "pattern": "git\\s+(reset|clean)\\s+--hard" },
// { "pattern": "git\\s+push\\s+(-f|--force)" },
// ],
// },
// "edit_file": {
// "default_mode": "confirm",
// "default": "confirm",
// "always_deny": [
// // Secrets and credentials
// { "pattern": "\\.env($|\\.)" },
Expand Down Expand Up @@ -2235,9 +2244,9 @@
// Whether to show the LSP servers button in the status bar.
"button": true,
// The maximum amount of time to wait for responses from language servers, in seconds.
// A value of 0 will result in no timeout being applied.
//
// A value of `0` will result in no timeout being applied (causing all LSP responses to wait
// indefinitely until completed).
// Default: 120
"request_timeout": 120,
"notifications": {
// Timeout in milliseconds for automatically dismissing language server notifications.
Expand Down
1 change: 0 additions & 1 deletion crates/acp_thread/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ test-support = ["gpui/test-support", "project/test-support", "dep:parking_lot",
action_log.workspace = true
agent-client-protocol.workspace = true
base64.workspace = true
agent_settings.workspace = true
anyhow.workspace = true
buffer_diff.workspace = true
chrono.workspace = true
Expand Down
19 changes: 1 addition & 18 deletions crates/acp_thread/src/acp_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ mod diff;
mod mention;
mod terminal;

use agent_settings::AgentSettings;

/// Key used in ACP ToolCall meta to store the tool's programmatic name.
/// This is a workaround since ACP's ToolCall doesn't have a dedicated name field.
pub const TOOL_NAME_META_KEY: &str = "tool_name";
Expand Down Expand Up @@ -40,7 +38,7 @@ pub use mention::*;
use project::lsp_store::{FormatTrigger, LspFormatTarget};
use serde::{Deserialize, Serialize};
use serde_json::to_string_pretty;
use settings::Settings as _;

use task::{Shell, ShellBuilder};
pub use terminal::*;

Expand Down Expand Up @@ -1733,25 +1731,10 @@ impl AcpThread {
&mut self,
tool_call: acp::ToolCallUpdate,
options: PermissionOptions,
respect_always_allow_setting: bool,
cx: &mut Context<Self>,
) -> Result<BoxFuture<'static, acp::RequestPermissionOutcome>> {
let (tx, rx) = oneshot::channel();

if respect_always_allow_setting && AgentSettings::get_global(cx).always_allow_tool_actions {
// Don't use AllowAlways, because then if you were to turn off always_allow_tool_actions,
// some tools would (incorrectly) continue to auto-accept.
if let Some(allow_once_option) = options.allow_once_option_id() {
self.upsert_tool_call_inner(tool_call, ToolCallStatus::Pending, cx)?;
return Ok(async {
acp::RequestPermissionOutcome::Selected(acp::SelectedPermissionOutcome::new(
allow_once_option,
))
}
.boxed());
}
}

let status = ToolCallStatus::WaitingForConfirmation {
options,
respond_tx: tx,
Expand Down
6 changes: 5 additions & 1 deletion crates/acp_thread/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,11 @@ impl PermissionOptions {
self.first_option_of_kind(acp::PermissionOptionKind::AllowOnce)
.map(|option| option.option_id.clone())
}

pub fn deny_once_option_id(&self) -> Option<acp::PermissionOptionId> {
self.first_option_of_kind(acp::PermissionOptionKind::RejectOnce)
.map(|option| option.option_id.clone())
}
}

#[cfg(feature = "test-support")]
Expand Down Expand Up @@ -689,7 +694,6 @@ mod test_support {
thread.request_tool_call_authorization(
tool_call.clone().into(),
options.clone(),
false,
cx,
)
})??
Expand Down
5 changes: 2 additions & 3 deletions crates/agent/src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use context_server::ContextServerId;
pub use db::*;
pub use native_agent_server::NativeAgentServer;
pub use pattern_extraction::*;
pub use shell_command_parser::extract_commands;
pub use templates::*;
pub use thread::*;
pub use thread_store::*;
Expand Down Expand Up @@ -1038,9 +1039,7 @@ impl NativeAgentConnection {
context: _,
}) => {
let outcome_task = acp_thread.update(cx, |thread, cx| {
thread.request_tool_call_authorization(
tool_call, options, true, cx,
)
thread.request_tool_call_authorization(tool_call, options, cx)
})??;
cx.background_spawn(async move {
if let acp::RequestPermissionOutcome::Selected(
Expand Down
Loading