mirror of
https://github.com/openai/codex.git
synced 2026-04-24 06:35:50 +00:00
feat(tui) /permissions
This commit is contained in:
@@ -302,6 +302,7 @@ mod tests {
|
||||
cmds,
|
||||
vec![
|
||||
"model",
|
||||
"permissions",
|
||||
"experimental",
|
||||
"resume",
|
||||
"compact",
|
||||
|
||||
@@ -5,5 +5,5 @@ expression: terminal.backend()
|
||||
" "
|
||||
"› /mo "
|
||||
" "
|
||||
" /model choose what model and reasoning effort to use "
|
||||
" /mention mention a file "
|
||||
" /model choose what model and reasoning effort to "
|
||||
" use "
|
||||
|
||||
@@ -2254,6 +2254,9 @@ impl ChatWidget {
|
||||
SlashCommand::Approvals => {
|
||||
self.open_approvals_popup();
|
||||
}
|
||||
SlashCommand::Permissions => {
|
||||
self.open_permissions_popup();
|
||||
}
|
||||
SlashCommand::ElevateSandbox => {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
@@ -3519,6 +3522,42 @@ impl ChatWidget {
|
||||
|
||||
/// Open a popup to choose the approvals mode (ask for approval policy + sandbox policy).
|
||||
pub(crate) fn open_approvals_popup(&mut self) {
|
||||
self.open_approval_mode_popup(
|
||||
"Update Model Permissions",
|
||||
true,
|
||||
|preset, is_windows_degraded| {
|
||||
if preset.id == "auto" && is_windows_degraded {
|
||||
"Agent (non-elevated sandbox)".to_string()
|
||||
} else {
|
||||
preset.label.to_string()
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Open a popup to choose the permissions mode (approval policy + sandbox policy).
|
||||
pub(crate) fn open_permissions_popup(&mut self) {
|
||||
let include_read_only = cfg!(target_os = "windows");
|
||||
self.open_approval_mode_popup(
|
||||
"Update Model Permissions",
|
||||
include_read_only,
|
||||
|preset, _| match preset.id {
|
||||
"read-only" => "Read Only".to_string(),
|
||||
"auto" => "Default".to_string(),
|
||||
"full-access" => "Full Access".to_string(),
|
||||
_ => preset.label.to_string(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn open_approval_mode_popup<F>(
|
||||
&mut self,
|
||||
title: &str,
|
||||
include_read_only: bool,
|
||||
label_for_preset: F,
|
||||
) where
|
||||
F: Fn(&ApprovalPreset, bool) -> String,
|
||||
{
|
||||
let current_approval = self.config.approval_policy.value();
|
||||
let current_sandbox = self.config.sandbox_policy.get();
|
||||
let mut items: Vec<SelectionItem> = Vec::new();
|
||||
@@ -3535,13 +3574,12 @@ impl ChatWidget {
|
||||
&& presets.iter().any(|preset| preset.id == "auto");
|
||||
|
||||
for preset in presets.into_iter() {
|
||||
if !include_read_only && preset.id == "read-only" {
|
||||
continue;
|
||||
}
|
||||
let is_current =
|
||||
Self::preset_matches_current(current_approval, current_sandbox, &preset);
|
||||
let name = if preset.id == "auto" && windows_degraded_sandbox_enabled {
|
||||
"Agent (non-elevated sandbox)".to_string()
|
||||
} else {
|
||||
preset.label.to_string()
|
||||
};
|
||||
let name = label_for_preset(&preset, windows_degraded_sandbox_enabled);
|
||||
let description = Some(preset.description.to_string());
|
||||
let disabled_reason = match self.config.approval_policy.can_set(&preset.approval) {
|
||||
Ok(()) => None,
|
||||
@@ -3627,7 +3665,7 @@ impl ChatWidget {
|
||||
});
|
||||
|
||||
self.bottom_pane.show_selection_view(SelectionViewParams {
|
||||
title: Some("Select Approval Mode".to_string()),
|
||||
title: Some(title.to_string()),
|
||||
footer_note,
|
||||
footer_hint: Some(standard_popup_hint_line()),
|
||||
items,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
source: tui/src/chatwidget/tests.rs
|
||||
expression: popup
|
||||
---
|
||||
Select Approval Mode
|
||||
Update Model Permissions
|
||||
|
||||
› 1. Read Only (current) Requires approval to edit files and run commands.
|
||||
2. Agent Read and edit files, and run commands.
|
||||
|
||||
@@ -3010,7 +3010,7 @@ async fn approvals_popup_navigation_skips_disabled() {
|
||||
.expect("render approvals popup after disabled selection");
|
||||
let screen = terminal.backend().vt100().screen().contents();
|
||||
assert!(
|
||||
screen.contains("Select Approval Mode"),
|
||||
screen.contains("Update Model Permissions"),
|
||||
"popup should remain open after selecting a disabled entry"
|
||||
);
|
||||
assert!(
|
||||
|
||||
@@ -947,6 +947,11 @@ pub(crate) fn new_session_info(
|
||||
"/approvals".into(),
|
||||
" - choose what Codex can do without approval".dim(),
|
||||
]),
|
||||
Line::from(vec![
|
||||
" ".into(),
|
||||
"/permissions".into(),
|
||||
" - choose what Codex is allowed to do".dim(),
|
||||
]),
|
||||
Line::from(vec![
|
||||
" ".into(),
|
||||
"/model".into(),
|
||||
|
||||
@@ -14,6 +14,7 @@ pub enum SlashCommand {
|
||||
// more frequently used commands should be listed first.
|
||||
Model,
|
||||
Approvals,
|
||||
Permissions,
|
||||
#[strum(serialize = "setup-elevated-sandbox")]
|
||||
ElevateSandbox,
|
||||
Experimental,
|
||||
@@ -60,6 +61,7 @@ impl SlashCommand {
|
||||
SlashCommand::Model => "choose what model and reasoning effort to use",
|
||||
SlashCommand::Collab => "change collaboration mode (experimental)",
|
||||
SlashCommand::Approvals => "choose what Codex can do without approval",
|
||||
SlashCommand::Permissions => "choose what Codex is allowed to do",
|
||||
SlashCommand::ElevateSandbox => "set up elevated agent sandbox",
|
||||
SlashCommand::Experimental => "toggle beta features",
|
||||
SlashCommand::Mcp => "list configured MCP tools",
|
||||
@@ -86,6 +88,7 @@ impl SlashCommand {
|
||||
// | SlashCommand::Undo
|
||||
| SlashCommand::Model
|
||||
| SlashCommand::Approvals
|
||||
| SlashCommand::Permissions
|
||||
| SlashCommand::ElevateSandbox
|
||||
| SlashCommand::Experimental
|
||||
| SlashCommand::Review
|
||||
|
||||
Reference in New Issue
Block a user