use std::path::PathBuf;use codex_app_server_protocol::AskForApproval;use codex_app_server_protocol::CommandExecutionApprovalDecision;use codex_app_server_protocol::FileChangeApprovalDecision;use codex_app_server_protocol::McpServerElicitationAction;use codex_app_server_protocol::RequestId as AppServerRequestId;use codex_app_server_protocol::ReviewTarget;use codex_app_server_protocol::ToolRequestUserInputResponse;use codex_app_server_protocol::UserInput;use codex_config::types::ApprovalsReviewer;use codex_protocol::approvals::GuardianAssessmentEvent;use codex_protocol::config_types::CollaborationMode;use codex_protocol::config_types::Personality;use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig;use codex_protocol::config_types::WindowsSandboxLevel;use codex_protocol::models::ActivePermissionProfile;use codex_protocol::models::PermissionProfile;use codex_protocol::openai_models::ReasoningEffort as ReasoningEffortConfig;use codex_protocol::request_permissions::RequestPermissionsResponse;use serde::Serialize;use serde_json::Value;#[allow(clippy::large_enum_variant)]#[derive(Debug, Clone, PartialEq, Serialize)]pub(crate) enum AppCommand { Interrupt { behavior: InterruptBehavior, }, CleanBackgroundTerminals, RunUserShellCommand { command: String, }, UserTurn { items: Vec<UserInput>, cwd: PathBuf, approval_policy: AskForApproval, approvals_reviewer: Option<ApprovalsReviewer>, active_permission_profile: Option<ActivePermissionProfile>, model: String, effort: Option<ReasoningEffortConfig>, summary: Option<ReasoningSummaryConfig>, service_tier: Option<Option<String>>, final_output_json_schema: Option<Value>, collaboration_mode: Option<CollaborationMode>, personality: Option<Personality>, }, OverrideTurnContext { cwd: Option<PathBuf>, approval_policy: Option<AskForApproval>, approvals_reviewer: Option<ApprovalsReviewer>, permission_profile: Option<PermissionProfile>, active_permission_profile: Option<ActivePermissionProfile>, windows_sandbox_level: Option<WindowsSandboxLevel>, model: Option<String>, effort: Option<Option<ReasoningEffortConfig>>, summary: Option<ReasoningSummaryConfig>, service_tier: Option<Option<String>>, collaboration_mode: Option<CollaborationMode>, personality: Option<Personality>, }, ExecApproval { id: String, turn_id: Option<String>, decision: CommandExecutionApprovalDecision, }, PatchApproval { id: String, decision: FileChangeApprovalDecision, }, ResolveElicitation { server_name: String, request_id: AppServerRequestId, decision: McpServerElicitationAction, content: Option<Value>, meta: Option<Value>, }, UserInputAnswer { id: String, response: ToolRequestUserInputResponse, }, RequestPermissionsResponse { id: String, response: RequestPermissionsResponse, }, ReloadUserConfig, ListSkills { cwds: Vec<PathBuf>, force_reload: bool, }, Compact, SetThreadName { name: String, }, Shutdown, ThreadRollback { num_turns: u32, }, Review { target: ReviewTarget, }, ApproveGuardianDeniedAction { event: GuardianAssessmentEvent, },}#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]pub(crate) enum InterruptBehavior { Default, RestorePromptIfNoOutput,}impl AppCommand { pub(crate) fn interrupt() -> Self { Self::Interrupt { behavior: InterruptBehavior::Default, } } pub(crate) fn interrupt_and_restore_prompt_if_no_output() -> Self { Self::Interrupt { behavior: InterruptBehavior::RestorePromptIfNoOutput, } } pub(crate) fn clean_background_terminals() -> Self { Self::CleanBackgroundTerminals } pub(crate) fn run_user_shell_command(command: String) -> Self { Self::RunUserShellCommand { command } } #[allow(clippy::too_many_arguments)] pub(crate) fn user_turn( items: Vec<UserInput>, cwd: PathBuf, approval_policy: AskForApproval, active_permission_profile: Option<ActivePermissionProfile>, model: String, effort: Option<ReasoningEffortConfig>, summary: Option<ReasoningSummaryConfig>, service_tier: Option<Option<String>>, final_output_json_schema: Option<Value>, collaboration_mode: Option<CollaborationMode>, personality: Option<Personality>, ) -> Self { Self::UserTurn { items, cwd, approval_policy, approvals_reviewer: None, active_permission_profile, model, effort, summary, service_tier, final_output_json_schema, collaboration_mode, personality, } } #[allow(clippy::too_many_arguments)] pub(crate) fn override_turn_context( cwd: Option<PathBuf>, approval_policy: Option<AskForApproval>, approvals_reviewer: Option<ApprovalsReviewer>, permission_profile: Option<PermissionProfile>, active_permission_profile: Option<ActivePermissionProfile>, windows_sandbox_level: Option<WindowsSandboxLevel>, model: Option<String>, effort: Option<Option<ReasoningEffortConfig>>, summary: Option<ReasoningSummaryConfig>, service_tier: Option<Option<String>>, collaboration_mode: Option<CollaborationMode>, personality: Option<Personality>, ) -> Self { Self::OverrideTurnContext { cwd, approval_policy, approvals_reviewer, permission_profile, active_permission_profile, windows_sandbox_level, model, effort, summary, service_tier, collaboration_mode, personality, } } pub(crate) fn exec_approval( id: String, turn_id: Option<String>, decision: CommandExecutionApprovalDecision, ) -> Self { Self::ExecApproval { id, turn_id, decision, } } pub(crate) fn patch_approval(id: String, decision: FileChangeApprovalDecision) -> Self { Self::PatchApproval { id, decision } } pub(crate) fn resolve_elicitation( server_name: String, request_id: AppServerRequestId, decision: McpServerElicitationAction, content: Option<Value>, meta: Option<Value>, ) -> Self { Self::ResolveElicitation { server_name, request_id, decision, content, meta, } } pub(crate) fn user_input_answer(id: String, response: ToolRequestUserInputResponse) -> Self { Self::UserInputAnswer { id, response } } pub(crate) fn request_permissions_response( id: String, response: RequestPermissionsResponse, ) -> Self { Self::RequestPermissionsResponse { id, response } } pub(crate) fn reload_user_config() -> Self { Self::ReloadUserConfig } pub(crate) fn list_skills(cwds: Vec<PathBuf>, force_reload: bool) -> Self { Self::ListSkills { cwds, force_reload } } pub(crate) fn compact() -> Self { Self::Compact } pub(crate) fn set_thread_name(name: String) -> Self { Self::SetThreadName { name } } #[allow(dead_code)] pub(crate) fn shutdown() -> Self { Self::Shutdown } pub(crate) fn thread_rollback(num_turns: u32) -> Self { Self::ThreadRollback { num_turns } } pub(crate) fn review(target: ReviewTarget) -> Self { Self::Review { target } } pub(crate) fn approve_guardian_denied_action(event: GuardianAssessmentEvent) -> Self { Self::ApproveGuardianDeniedAction { event } } pub(crate) fn is_review(&self) -> bool { matches!(self, Self::Review { .. }) }}impl From<&AppCommand> for AppCommand { fn from(value: &AppCommand) -> Self { value.clone() }}