Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 0 additions & 20 deletions codex-rs/app-server-protocol/schema/json/ClientRequest.json

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

20 changes: 0 additions & 20 deletions codex-rs/app-server-protocol/schema/json/v2/CommandExecParams.json

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

16 changes: 3 additions & 13 deletions codex-rs/app-server-protocol/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2747,7 +2747,6 @@ export type Config = { stableField: Keep, unstableField: string | null } & ({ [k
let _guard = TempDirGuard(output_dir.clone());
let path = output_dir.join("CommandExecParams.ts");
let content = r#"import type { CommandExecTerminalSize } from "./CommandExecTerminalSize";
import type { ActivePermissionProfile } from "./ActivePermissionProfile";
import type { SandboxPolicy } from "./SandboxPolicy";

export type CommandExecParams = {/**
Expand All @@ -2770,12 +2769,12 @@ size?: CommandExecTerminalSize | null, /**
*/
sandboxPolicy?: SandboxPolicy | null,
/**
* Optional active permissions profile for this command.
* Optional active permissions profile id for this command.
*
* Defaults to the user's configured permissions when omitted. Cannot be
* combined with `sandboxPolicy`.
*/
permissionProfile?: ActivePermissionProfile | null};
permissionProfile?: string | null};
"#;
fs::write(&path, content)?;

Expand All @@ -2788,16 +2787,7 @@ permissionProfile?: ActivePermissionProfile | null};
filter_experimental_type_fields_ts(&output_dir, &[&CUSTOM_FIELD])?;

let filtered = fs::read_to_string(&path)?;
assert_eq!(
filtered.contains("permissionProfile?: ActivePermissionProfile"),
false
);
assert_eq!(
filtered.contains(
r#"import type { ActivePermissionProfile } from "./ActivePermissionProfile";"#
),
false
);
assert_eq!(filtered.contains("permissionProfile?: string"), false);
assert_eq!(filtered.contains("sandboxPolicy?: SandboxPolicy"), true);
assert_eq!(
filtered.contains(r#"import type { SandboxPolicy } from "./SandboxPolicy";"#),
Expand Down
3 changes: 2 additions & 1 deletion codex-rs/app-server-protocol/src/protocol/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1555,6 +1555,7 @@ mod tests {
use anyhow::Result;
use codex_protocol::ThreadId;
use codex_protocol::account::PlanType;
use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_READ_ONLY;
use codex_protocol::parse_command::ParsedCommand;
use codex_protocol::protocol::RealtimeConversationVersion;
use codex_protocol::protocol::RealtimeOutputModality;
Expand Down Expand Up @@ -2994,7 +2995,7 @@ mod tests {
env: None,
size: None,
sandbox_policy: None,
permission_profile: Some(v2::ActivePermissionProfile::read_only()),
permission_profile: Some(BUILT_IN_PERMISSION_PROFILE_READ_ONLY.to_string()),
},
};

Expand Down
5 changes: 2 additions & 3 deletions codex-rs/app-server-protocol/src/protocol/v2/command_exec.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use super::ActivePermissionProfile;
use super::SandboxPolicy;
use codex_experimental_api_macros::ExperimentalApi;
use schemars::JsonSchema;
Expand Down Expand Up @@ -100,13 +99,13 @@ pub struct CommandExecParams {
/// combined with `permissionProfile`.
#[ts(optional = nullable)]
pub sandbox_policy: Option<SandboxPolicy>,
/// Optional active permissions profile for this command.
/// Optional active permissions profile id for this command.
///
/// Defaults to the user's configured permissions when omitted. Cannot be
/// combined with `sandboxPolicy`.
#[experimental("command/exec.permissionProfile")]
#[ts(optional = nullable)]
pub permission_profile: Option<ActivePermissionProfile>,
pub permission_profile: Option<String>,
}

/// Final buffered result for `command/exec`.
Expand Down
98 changes: 0 additions & 98 deletions codex-rs/app-server-protocol/src/protocol/v2/permissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ use codex_protocol::request_permissions::RequestPermissionProfile as CoreRequest
use codex_utils_absolute_path::AbsolutePathBuf;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Deserializer;
use serde::Serialize;
use serde::Serializer;
use std::num::NonZeroUsize;
use std::path::PathBuf;
use ts_rs::TS;
Expand Down Expand Up @@ -333,102 +331,6 @@ impl From<ActivePermissionProfile> for CoreActivePermissionProfile {
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PermissionProfileSelectionParams {
id: String,
legacy_additional_writable_roots: Vec<AbsolutePathBuf>,
}

impl PermissionProfileSelectionParams {
pub fn new(id: impl Into<String>) -> Self {
Self {
id: id.into(),
legacy_additional_writable_roots: Vec::new(),
}
}

pub fn id(&self) -> &str {
&self.id
}

pub fn into_id(self) -> String {
self.id
}

pub fn legacy_additional_writable_roots(&self) -> &[AbsolutePathBuf] {
&self.legacy_additional_writable_roots
}
}

impl From<String> for PermissionProfileSelectionParams {
fn from(id: String) -> Self {
Self::new(id)
}
}

impl Serialize for PermissionProfileSelectionParams {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.id)
}
}

impl<'de> Deserialize<'de> for PermissionProfileSelectionParams {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum Wire {
Id(String),
LegacyProfile {
#[serde(rename = "type")]
_type: LegacyPermissionProfileSelectionType,
id: String,
#[serde(default)]
modifications: Option<Vec<LegacyPermissionProfileModificationParams>>,
},
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
enum LegacyPermissionProfileSelectionType {
Profile,
}

#[derive(Deserialize)]
#[serde(tag = "type", rename_all = "camelCase")]
enum LegacyPermissionProfileModificationParams {
#[serde(rename_all = "camelCase")]
AdditionalWritableRoot { path: AbsolutePathBuf },
}

match Wire::deserialize(deserializer)? {
Wire::Id(id) => Ok(Self::new(id)),
Wire::LegacyProfile {
id, modifications, ..
} => {
let legacy_additional_writable_roots = modifications
.unwrap_or_default()
.into_iter()
.map(|modification| match modification {
LegacyPermissionProfileModificationParams::AdditionalWritableRoot {
path,
} => path,
})
.collect();
Ok(Self {
id,
legacy_additional_writable_roots,
})
}
}
}
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
Expand Down
71 changes: 32 additions & 39 deletions codex-rs/app-server-protocol/src/protocol/v2/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use codex_protocol::mcp::CallToolResult;
use codex_protocol::memory_citation::MemoryCitation as CoreMemoryCitation;
use codex_protocol::memory_citation::MemoryCitationEntry as CoreMemoryCitationEntry;
use codex_protocol::models::AdditionalPermissionProfile as CoreAdditionalPermissionProfile;
use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_WORKSPACE;
use codex_protocol::models::FileSystemPermissions as CoreFileSystemPermissions;
use codex_protocol::models::ImageDetail;
use codex_protocol::models::MessagePhase;
Expand Down Expand Up @@ -614,57 +615,49 @@ fn permissions_request_approval_response_accepts_strict_auto_review() {
}

#[test]
fn permission_profile_selection_accepts_legacy_object_shape() {
let additional_root = absolute_path("additional-root");
let params = json!({
"permissions": {
"type": "profile",
"id": ":workspace",
"modifications": [
{
"type": "additionalWritableRoot",
"path": additional_root,
}
],
},
});
fn permission_profile_selection_uses_id_string() {
let start: ThreadStartParams = serde_json::from_value(json!({
"permissions": BUILT_IN_PERMISSION_PROFILE_WORKSPACE,
}))
.expect("thread/start params deserialize");
assert_eq!(
start.permissions,
Some(BUILT_IN_PERMISSION_PROFILE_WORKSPACE.to_string())
);

let turn: TurnStartParams = serde_json::from_value(json!({
"threadId": "thread-1",
"input": [],
"permissions": "dev",
}))
.expect("turn/start params deserialize");
assert_eq!(turn.permissions, Some("dev".to_string()));

let start: ThreadStartParams =
serde_json::from_value(params.clone()).expect("thread/start params deserialize");
assert_legacy_permission_profile_selection(start.permissions, &additional_root);
let command: CommandExecParams = serde_json::from_value(json!({
"command": ["echo", "hello"],
"permissionProfile": "dev",
}))
.expect("command/exec params deserialize");
assert_eq!(command.permission_profile, Some("dev".to_string()));

let resume: ThreadResumeParams = serde_json::from_value(json!({
"threadId": "thread-1",
"permissions": params["permissions"].clone(),
"permissions": BUILT_IN_PERMISSION_PROFILE_WORKSPACE,
}))
.expect("thread/resume params deserialize");
assert_legacy_permission_profile_selection(resume.permissions, &additional_root);
assert_eq!(
resume.permissions,
Some(BUILT_IN_PERMISSION_PROFILE_WORKSPACE.to_string())
);

let fork: ThreadForkParams = serde_json::from_value(json!({
"threadId": "thread-1",
"permissions": params["permissions"].clone(),
"permissions": BUILT_IN_PERMISSION_PROFILE_WORKSPACE,
}))
.expect("thread/fork params deserialize");
assert_legacy_permission_profile_selection(fork.permissions, &additional_root);

let turn: TurnStartParams = serde_json::from_value(json!({
"threadId": "thread-1",
"input": [],
"permissions": params["permissions"].clone(),
}))
.expect("turn/start params deserialize");
assert_legacy_permission_profile_selection(turn.permissions, &additional_root);
}

fn assert_legacy_permission_profile_selection(
selection: Option<PermissionProfileSelectionParams>,
additional_root: &AbsolutePathBuf,
) {
let selection = selection.expect("permissions should be present");
assert_eq!(selection.id(), ":workspace");
assert_eq!(
selection.legacy_additional_writable_roots(),
std::slice::from_ref(additional_root)
fork.permissions,
Some(BUILT_IN_PERMISSION_PROFILE_WORKSPACE.to_string())
);
}

Expand Down
13 changes: 3 additions & 10 deletions codex-rs/app-server-protocol/src/protocol/v2/thread.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use super::ActivePermissionProfile;
use super::ApprovalsReviewer;
use super::AskForApproval;
use super::PermissionProfileSelectionParams;
use super::SandboxMode;
use super::SandboxPolicy;
use super::Thread;
Expand Down Expand Up @@ -122,10 +121,8 @@ pub struct ThreadStartParams {
pub sandbox: Option<SandboxMode>,
/// Named profile id for this thread. Cannot be combined with `sandbox`.
#[experimental("thread/start.permissions")]
#[schemars(with = "Option<String>")]
#[ts(type = "string | null")]
#[ts(optional = nullable)]
pub permissions: Option<PermissionProfileSelectionParams>,
pub permissions: Option<String>,
#[ts(optional = nullable)]
pub config: Option<HashMap<String, JsonValue>>,
#[ts(optional = nullable)]
Expand Down Expand Up @@ -284,10 +281,8 @@ pub struct ThreadResumeParams {
/// Named profile id for the resumed thread. Cannot be combined with
/// `sandbox`.
#[experimental("thread/resume.permissions")]
#[schemars(with = "Option<String>")]
#[ts(type = "string | null")]
#[ts(optional = nullable)]
pub permissions: Option<PermissionProfileSelectionParams>,
pub permissions: Option<String>,
#[ts(optional = nullable)]
pub config: Option<HashMap<String, serde_json::Value>>,
#[ts(optional = nullable)]
Expand Down Expand Up @@ -395,10 +390,8 @@ pub struct ThreadForkParams {
/// Named profile id for the forked thread. Cannot be combined with
/// `sandbox`.
#[experimental("thread/fork.permissions")]
#[schemars(with = "Option<String>")]
#[ts(type = "string | null")]
#[ts(optional = nullable)]
pub permissions: Option<PermissionProfileSelectionParams>,
pub permissions: Option<String>,
#[ts(optional = nullable)]
pub config: Option<HashMap<String, serde_json::Value>>,
#[ts(optional = nullable)]
Expand Down
Loading
Loading