mirror of
https://github.com/openai/codex.git
synced 2026-03-06 06:33:21 +00:00
Compare commits
3 Commits
fix/notify
...
dh--permis
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d98928c00 | ||
|
|
24ab98ed85 | ||
|
|
df6a95ce9c |
@@ -38,7 +38,7 @@ pub fn builtin_approval_presets() -> Vec<ApprovalPreset> {
|
||||
ApprovalPreset {
|
||||
id: "full-access",
|
||||
label: "Agent (full access)",
|
||||
description: "Codex can edit files outside this workspace and run commands with network access. Exercise caution when using.",
|
||||
description: "Codex can edit files outside this workspace and access the internet. Exercise caution when using.",
|
||||
approval: AskForApproval::Never,
|
||||
sandbox: SandboxPolicy::DangerFullAccess,
|
||||
},
|
||||
|
||||
@@ -997,8 +997,12 @@ impl App {
|
||||
AppEvent::OpenAllModelsPopup { models } => {
|
||||
self.chat_widget.open_all_models_popup(models);
|
||||
}
|
||||
AppEvent::OpenFullAccessConfirmation { preset } => {
|
||||
self.chat_widget.open_full_access_confirmation(preset);
|
||||
AppEvent::OpenFullAccessConfirmation {
|
||||
preset,
|
||||
return_to_permissions,
|
||||
} => {
|
||||
self.chat_widget
|
||||
.open_full_access_confirmation(preset, return_to_permissions);
|
||||
}
|
||||
AppEvent::OpenWorldWritableWarningConfirmation {
|
||||
preset,
|
||||
@@ -1383,6 +1387,9 @@ impl App {
|
||||
AppEvent::OpenApprovalsPopup => {
|
||||
self.chat_widget.open_approvals_popup();
|
||||
}
|
||||
AppEvent::OpenPermissionsPopup => {
|
||||
self.chat_widget.open_permissions_popup();
|
||||
}
|
||||
AppEvent::OpenReviewBranchPicker(cwd) => {
|
||||
self.chat_widget.show_review_branch_picker(&cwd).await;
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ pub(crate) enum AppEvent {
|
||||
/// Open the confirmation prompt before enabling full access mode.
|
||||
OpenFullAccessConfirmation {
|
||||
preset: ApprovalPreset,
|
||||
return_to_permissions: bool,
|
||||
},
|
||||
|
||||
/// Open the Windows world-writable directories warning.
|
||||
@@ -212,6 +213,9 @@ pub(crate) enum AppEvent {
|
||||
/// Re-open the approval presets popup.
|
||||
OpenApprovalsPopup,
|
||||
|
||||
/// Re-open the permissions presets popup.
|
||||
OpenPermissionsPopup,
|
||||
|
||||
/// Open the branch picker option from the review popup.
|
||||
OpenReviewBranchPicker(PathBuf),
|
||||
|
||||
|
||||
@@ -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,54 @@ 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,
|
||||
false,
|
||||
|preset, is_windows_degraded| {
|
||||
if preset.id == "auto" && is_windows_degraded {
|
||||
"Agent (non-elevated sandbox)".to_string()
|
||||
} else {
|
||||
preset.label.to_string()
|
||||
}
|
||||
},
|
||||
|preset| preset.description.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,
|
||||
true,
|
||||
|preset, _| match preset.id {
|
||||
"read-only" => "Read Only".to_string(),
|
||||
"auto" => "Default".to_string(),
|
||||
"full-access" => "Full Access".to_string(),
|
||||
_ => preset.label.to_string(),
|
||||
},
|
||||
|preset| match preset.id {
|
||||
"auto" => {
|
||||
format!("{} Identical to Agent approvals.", preset.description)
|
||||
}
|
||||
_ => preset.description.to_string(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn open_approval_mode_popup<F, D>(
|
||||
&mut self,
|
||||
title: &str,
|
||||
include_read_only: bool,
|
||||
return_to_permissions: bool,
|
||||
label_for_preset: F,
|
||||
description_for_preset: D,
|
||||
) where
|
||||
F: Fn(&ApprovalPreset, bool) -> String,
|
||||
D: Fn(&ApprovalPreset) -> 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,14 +3586,13 @@ 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 description = Some(preset.description.to_string());
|
||||
let name = label_for_preset(&preset, windows_degraded_sandbox_enabled);
|
||||
let description = Some(description_for_preset(&preset));
|
||||
let disabled_reason = match self.config.approval_policy.can_set(&preset.approval) {
|
||||
Ok(()) => None,
|
||||
Err(err) => Some(err.to_string()),
|
||||
@@ -3558,6 +3608,7 @@ impl ChatWidget {
|
||||
vec![Box::new(move |tx| {
|
||||
tx.send(AppEvent::OpenFullAccessConfirmation {
|
||||
preset: preset_clone.clone(),
|
||||
return_to_permissions,
|
||||
});
|
||||
})]
|
||||
} else if preset.id == "auto" {
|
||||
@@ -3627,7 +3678,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,
|
||||
@@ -3727,7 +3778,11 @@ impl ChatWidget {
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn open_full_access_confirmation(&mut self, preset: ApprovalPreset) {
|
||||
pub(crate) fn open_full_access_confirmation(
|
||||
&mut self,
|
||||
preset: ApprovalPreset,
|
||||
return_to_permissions: bool,
|
||||
) {
|
||||
let approval = preset.approval;
|
||||
let sandbox = preset.sandbox;
|
||||
let mut header_children: Vec<Box<dyn Renderable>> = Vec::new();
|
||||
@@ -3755,8 +3810,12 @@ impl ChatWidget {
|
||||
tx.send(AppEvent::PersistFullAccessWarningAcknowledged);
|
||||
}));
|
||||
|
||||
let deny_actions: Vec<SelectionAction> = vec![Box::new(|tx| {
|
||||
tx.send(AppEvent::OpenApprovalsPopup);
|
||||
let deny_actions: Vec<SelectionAction> = vec![Box::new(move |tx| {
|
||||
if return_to_permissions {
|
||||
tx.send(AppEvent::OpenPermissionsPopup);
|
||||
} else {
|
||||
tx.send(AppEvent::OpenApprovalsPopup);
|
||||
}
|
||||
})];
|
||||
|
||||
let items = vec![
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
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.
|
||||
3. Agent (full access) Codex can edit files outside this workspace and run
|
||||
commands with network access. Exercise caution when
|
||||
using.
|
||||
3. Agent (full access) Codex can edit files outside this workspace and
|
||||
access the internet. Exercise caution when using.
|
||||
|
||||
Press enter to confirm or esc to go back
|
||||
|
||||
@@ -2689,7 +2689,7 @@ async fn full_access_confirmation_popup_snapshot() {
|
||||
.into_iter()
|
||||
.find(|preset| preset.id == "full-access")
|
||||
.expect("full access preset");
|
||||
chat.open_full_access_confirmation(preset);
|
||||
chat.open_full_access_confirmation(preset, false);
|
||||
|
||||
let popup = render_bottom_popup(&chat, 80);
|
||||
assert_snapshot!("full_access_confirmation_popup", popup);
|
||||
@@ -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
|
||||
|
||||
@@ -1725,8 +1725,12 @@ impl App {
|
||||
AppEvent::OpenAllModelsPopup { models } => {
|
||||
self.chat_widget.open_all_models_popup(models);
|
||||
}
|
||||
AppEvent::OpenFullAccessConfirmation { preset } => {
|
||||
self.chat_widget.open_full_access_confirmation(preset);
|
||||
AppEvent::OpenFullAccessConfirmation {
|
||||
preset,
|
||||
return_to_permissions,
|
||||
} => {
|
||||
self.chat_widget
|
||||
.open_full_access_confirmation(preset, return_to_permissions);
|
||||
}
|
||||
AppEvent::OpenWorldWritableWarningConfirmation {
|
||||
preset,
|
||||
@@ -2070,6 +2074,9 @@ impl App {
|
||||
AppEvent::OpenApprovalsPopup => {
|
||||
self.chat_widget.open_approvals_popup();
|
||||
}
|
||||
AppEvent::OpenPermissionsPopup => {
|
||||
self.chat_widget.open_permissions_popup();
|
||||
}
|
||||
AppEvent::OpenReviewBranchPicker(cwd) => {
|
||||
self.chat_widget.show_review_branch_picker(&cwd).await;
|
||||
}
|
||||
|
||||
@@ -119,6 +119,7 @@ pub(crate) enum AppEvent {
|
||||
/// Open the confirmation prompt before enabling full access mode.
|
||||
OpenFullAccessConfirmation {
|
||||
preset: ApprovalPreset,
|
||||
return_to_permissions: bool,
|
||||
},
|
||||
|
||||
/// Open the Windows world-writable directories warning.
|
||||
@@ -201,6 +202,9 @@ pub(crate) enum AppEvent {
|
||||
/// Re-open the approval presets popup.
|
||||
OpenApprovalsPopup,
|
||||
|
||||
/// Re-open the permissions presets popup.
|
||||
OpenPermissionsPopup,
|
||||
|
||||
/// Open the branch picker option from the review popup.
|
||||
OpenReviewBranchPicker(PathBuf),
|
||||
|
||||
|
||||
@@ -297,7 +297,17 @@ mod tests {
|
||||
CommandItem::UserPrompt(_) => None,
|
||||
})
|
||||
.collect();
|
||||
assert_eq!(cmds, vec!["model", "resume", "compact", "mention", "mcp"]);
|
||||
assert_eq!(
|
||||
cmds,
|
||||
vec![
|
||||
"model",
|
||||
"permissions",
|
||||
"resume",
|
||||
"compact",
|
||||
"mention",
|
||||
"mcp"
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -559,7 +559,7 @@ mod tests {
|
||||
];
|
||||
ListSelectionView::new(
|
||||
SelectionViewParams {
|
||||
title: Some("Select Approval Mode".to_string()),
|
||||
title: Some("Update Model Permissions".to_string()),
|
||||
subtitle: subtitle.map(str::to_string),
|
||||
footer_hint: Some(standard_popup_hint_line()),
|
||||
items,
|
||||
@@ -629,7 +629,7 @@ mod tests {
|
||||
]);
|
||||
let view = ListSelectionView::new(
|
||||
SelectionViewParams {
|
||||
title: Some("Select Approval Mode".to_string()),
|
||||
title: Some("Update Model Permissions".to_string()),
|
||||
footer_note: Some(footer_note),
|
||||
footer_hint: Some(standard_popup_hint_line()),
|
||||
items,
|
||||
@@ -656,7 +656,7 @@ mod tests {
|
||||
}];
|
||||
let mut view = ListSelectionView::new(
|
||||
SelectionViewParams {
|
||||
title: Some("Select Approval Mode".to_string()),
|
||||
title: Some("Update Model Permissions".to_string()),
|
||||
footer_hint: Some(standard_popup_hint_line()),
|
||||
items,
|
||||
is_searchable: true,
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
---
|
||||
source: tui2/src/bottom_pane/list_selection_view.rs
|
||||
assertion_line: 640
|
||||
expression: "render_lines_with_width(&view, 40)"
|
||||
---
|
||||
|
||||
Select Approval Mode
|
||||
Update Model Permissions
|
||||
|
||||
› 1. Read Only (current) Codex can
|
||||
read files
|
||||
|
||||
@@ -3,7 +3,7 @@ source: tui2/src/bottom_pane/list_selection_view.rs
|
||||
expression: render_lines(&view)
|
||||
---
|
||||
|
||||
Select Approval Mode
|
||||
Update Model Permissions
|
||||
Switch between Codex approval presets
|
||||
|
||||
› 1. Read Only (current) Codex can read files
|
||||
|
||||
@@ -3,7 +3,7 @@ source: tui2/src/bottom_pane/list_selection_view.rs
|
||||
expression: render_lines(&view)
|
||||
---
|
||||
|
||||
Select Approval Mode
|
||||
Update Model Permissions
|
||||
|
||||
› 1. Read Only (current) Codex can read files
|
||||
2. Full Access Codex can edit files
|
||||
|
||||
@@ -2020,6 +2020,9 @@ impl ChatWidget {
|
||||
SlashCommand::Approvals => {
|
||||
self.open_approvals_popup();
|
||||
}
|
||||
SlashCommand::Permissions => {
|
||||
self.open_permissions_popup();
|
||||
}
|
||||
SlashCommand::ElevateSandbox => {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
@@ -3225,6 +3228,52 @@ 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,
|
||||
false,
|
||||
|preset, is_windows_degraded| {
|
||||
if preset.id == "auto" && is_windows_degraded {
|
||||
"Agent (non-elevated sandbox)".to_string()
|
||||
} else {
|
||||
preset.label.to_string()
|
||||
}
|
||||
},
|
||||
|preset| preset.description.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,
|
||||
true,
|
||||
|preset, _| match preset.id {
|
||||
"read-only" => "Read Only".to_string(),
|
||||
"auto" => "Default".to_string(),
|
||||
"full-access" => "Full Access".to_string(),
|
||||
_ => preset.label.to_string(),
|
||||
},
|
||||
|preset| match preset.id {
|
||||
"auto" => format!("{} Identical to Agent approvals.", preset.description),
|
||||
_ => preset.description.to_string(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn open_approval_mode_popup<F, D>(
|
||||
&mut self,
|
||||
title: &str,
|
||||
include_read_only: bool,
|
||||
return_to_permissions: bool,
|
||||
label_for_preset: F,
|
||||
description_for_preset: D,
|
||||
) where
|
||||
F: Fn(&ApprovalPreset, bool) -> String,
|
||||
D: Fn(&ApprovalPreset) -> String,
|
||||
{
|
||||
let current_approval = self.config.approval_policy.value();
|
||||
let current_sandbox = self.config.sandbox_policy.get();
|
||||
let mut items: Vec<SelectionItem> = Vec::new();
|
||||
@@ -3241,15 +3290,13 @@ 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 description_text = preset.description;
|
||||
let description = Some(description_text.to_string());
|
||||
let name = label_for_preset(&preset, windows_degraded_sandbox_enabled);
|
||||
let description = Some(description_for_preset(&preset));
|
||||
let requires_confirmation = preset.id == "full-access"
|
||||
&& !self
|
||||
.config
|
||||
@@ -3261,6 +3308,7 @@ impl ChatWidget {
|
||||
vec![Box::new(move |tx| {
|
||||
tx.send(AppEvent::OpenFullAccessConfirmation {
|
||||
preset: preset_clone.clone(),
|
||||
return_to_permissions,
|
||||
});
|
||||
})]
|
||||
} else if preset.id == "auto" {
|
||||
@@ -3329,7 +3377,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,
|
||||
@@ -3410,7 +3458,11 @@ impl ChatWidget {
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn open_full_access_confirmation(&mut self, preset: ApprovalPreset) {
|
||||
pub(crate) fn open_full_access_confirmation(
|
||||
&mut self,
|
||||
preset: ApprovalPreset,
|
||||
return_to_permissions: bool,
|
||||
) {
|
||||
let approval = preset.approval;
|
||||
let sandbox = preset.sandbox;
|
||||
let mut header_children: Vec<Box<dyn Renderable>> = Vec::new();
|
||||
@@ -3438,8 +3490,12 @@ impl ChatWidget {
|
||||
tx.send(AppEvent::PersistFullAccessWarningAcknowledged);
|
||||
}));
|
||||
|
||||
let deny_actions: Vec<SelectionAction> = vec![Box::new(|tx| {
|
||||
tx.send(AppEvent::OpenApprovalsPopup);
|
||||
let deny_actions: Vec<SelectionAction> = vec![Box::new(move |tx| {
|
||||
if return_to_permissions {
|
||||
tx.send(AppEvent::OpenPermissionsPopup);
|
||||
} else {
|
||||
tx.send(AppEvent::OpenApprovalsPopup);
|
||||
}
|
||||
})];
|
||||
|
||||
let items = vec![
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
source: tui2/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.
|
||||
3. Agent (full access) Codex can edit files outside this workspace and run
|
||||
commands with network access. Exercise caution when
|
||||
using.
|
||||
3. Agent (full access) Codex can edit files outside this workspace and
|
||||
access the internet. Exercise caution when using.
|
||||
|
||||
Press enter to confirm or esc to go back
|
||||
|
||||
@@ -2404,7 +2404,7 @@ async fn full_access_confirmation_popup_snapshot() {
|
||||
.into_iter()
|
||||
.find(|preset| preset.id == "full-access")
|
||||
.expect("full access preset");
|
||||
chat.open_full_access_confirmation(preset);
|
||||
chat.open_full_access_confirmation(preset, false);
|
||||
|
||||
let popup = render_bottom_popup(&chat, 80);
|
||||
assert_snapshot!("full_access_confirmation_popup", popup);
|
||||
|
||||
@@ -1009,6 +1009,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,
|
||||
Skills,
|
||||
@@ -57,6 +58,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::Mcp => "list configured MCP tools",
|
||||
SlashCommand::Logout => "log out of Codex",
|
||||
@@ -82,6 +84,7 @@ impl SlashCommand {
|
||||
// | SlashCommand::Undo
|
||||
| SlashCommand::Model
|
||||
| SlashCommand::Approvals
|
||||
| SlashCommand::Permissions
|
||||
| SlashCommand::ElevateSandbox
|
||||
| SlashCommand::Review
|
||||
| SlashCommand::Logout => false,
|
||||
|
||||
Reference in New Issue
Block a user