Skip to content

Commit a4cb97b

Browse files
authored
Chore: add cmd related info to exec approval request (openai#9659)
### Summary We now rely purely on `item/commandExecution/requestApproval` item to render pending approval in VSCE and app. With v2 approach, it does not include the actual cmd that it is attempting and therefore we can only use `proposedExecpolicyAmendment` to render which can be incomplete. ### Reproduce * Add `prefix_rule(pattern=["echo"], decision="prompt")` to your `~/.codex/rules.default.rules`. * Ask to `Run echo "approval-test" please` in VSCE or app. * The pending approval protal does show up but with no content #### Example screenshot <img width="3434" height="3648" alt="Screenshot 2026-01-21 at 8 23 25 PM" src="https://github.com/user-attachments/assets/75644837-21f1-40f8-8b02-858d361ff817" /> #### Sample output ``` {"method":"item/commandExecution/requestApproval","id":0,"params":{ "threadId":"019be439-5a90-7600-a7ea-2d2dcc50302a", "turnId":"0", "itemId":"call_usgnQ4qEX5U9roNdjT7fPzhb", "reason":"`/bin/zsh -lc 'echo \"testing\"'` requires approval by policy", "proposedExecpolicyAmendment":null }} ``` ### Fix Inlude `command` string, `cwd` and `command_actions` in `CommandExecutionRequestApprovalParams` so that consumers can display the correct command instead of relying on exec policy output.
1 parent 079fd2a commit a4cb97b

File tree

4 files changed

+30
-1
lines changed

4 files changed

+30
-1
lines changed

codex-rs/app-server-protocol/src/protocol/v2.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,6 +2263,18 @@ pub struct CommandExecutionRequestApprovalParams {
22632263
pub item_id: String,
22642264
/// Optional explanatory reason (e.g. request for network access).
22652265
pub reason: Option<String>,
2266+
/// The command to be executed.
2267+
#[serde(default, skip_serializing_if = "Option::is_none")]
2268+
#[ts(optional)]
2269+
pub command: Option<String>,
2270+
/// The command's working directory.
2271+
#[serde(default, skip_serializing_if = "Option::is_none")]
2272+
#[ts(optional)]
2273+
pub cwd: Option<PathBuf>,
2274+
/// Best-effort parsed command actions for friendly display.
2275+
#[serde(default, skip_serializing_if = "Option::is_none")]
2276+
#[ts(optional)]
2277+
pub command_actions: Option<Vec<CommandAction>>,
22662278
/// Optional proposed execpolicy amendment to allow similar commands without prompting.
22672279
pub proposed_execpolicy_amendment: Option<ExecPolicyAmendment>,
22682280
}

codex-rs/app-server-test-client/src/main.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,9 @@ impl CodexClient {
842842
turn_id,
843843
item_id,
844844
reason,
845+
command,
846+
cwd,
847+
command_actions,
845848
proposed_execpolicy_amendment,
846849
} = params;
847850

@@ -851,6 +854,17 @@ impl CodexClient {
851854
if let Some(reason) = reason.as_deref() {
852855
println!("< reason: {reason}");
853856
}
857+
if let Some(command) = command.as_deref() {
858+
println!("< command: {command}");
859+
}
860+
if let Some(cwd) = cwd.as_ref() {
861+
println!("< cwd: {}", cwd.display());
862+
}
863+
if let Some(command_actions) = command_actions.as_ref()
864+
&& !command_actions.is_empty()
865+
{
866+
println!("< command actions: {command_actions:?}");
867+
}
854868
if let Some(execpolicy_amendment) = proposed_execpolicy_amendment.as_ref() {
855869
println!("< proposed execpolicy amendment: {execpolicy_amendment:?}");
856870
}

codex-rs/app-server/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ Certain actions (shell commands or modifying files) may require explicit user ap
445445
Order of messages:
446446

447447
1. `item/started` — shows the pending `commandExecution` item with `command`, `cwd`, and other fields so you can render the proposed action.
448-
2. `item/commandExecution/requestApproval` (request) — carries the same `itemId`, `threadId`, `turnId`, optionally `reason` or `risk`, plus `parsedCmd` for friendly display.
448+
2. `item/commandExecution/requestApproval` (request) — carries the same `itemId`, `threadId`, `turnId`, optionally `reason`, plus `command`, `cwd`, and `commandActions` for friendly display.
449449
3. Client response — `{ "decision": "accept", "acceptSettings": { "forSession": false } }` or `{ "decision": "decline" }`.
450450
4. `item/completed` — final `commandExecution` item with `status: "completed" | "failed" | "declined"` and execution output. Render this as the authoritative result.
451451

codex-rs/app-server/src/bespoke_event_handling.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,9 @@ pub(crate) async fn apply_bespoke_event_handling(
241241
// and emit the corresponding EventMsg, we repurpose the call_id as the item_id.
242242
item_id: item_id.clone(),
243243
reason,
244+
command: Some(command_string.clone()),
245+
cwd: Some(cwd.clone()),
246+
command_actions: Some(command_actions.clone()),
244247
proposed_execpolicy_amendment: proposed_execpolicy_amendment_v2,
245248
};
246249
let rx = outgoing

0 commit comments

Comments
 (0)