codex_utils_cli/
shared_options.rs1use crate::SandboxModeCliArg;
4use clap::Args;
5use codex_protocol::config_types::ProfileV2Name;
6use std::path::PathBuf;
7
8#[derive(Args, Clone, Debug, Default)]
9pub struct SharedCliOptions {
10 #[arg(
12 long = "image",
13 short = 'i',
14 value_name = "FILE",
15 value_delimiter = ',',
16 num_args = 1..
17 )]
18 pub images: Vec<PathBuf>,
19
20 #[arg(long, short = 'm')]
22 pub model: Option<String>,
23
24 #[arg(long = "oss", default_value_t = false)]
26 pub oss: bool,
27
28 #[arg(long = "local-provider")]
31 pub oss_provider: Option<String>,
32
33 #[arg(long = "profile", short = 'p')]
35 pub config_profile_v2: Option<ProfileV2Name>,
36
37 #[arg(long = "sandbox", short = 's')]
40 pub sandbox_mode: Option<SandboxModeCliArg>,
41
42 #[arg(
45 long = "dangerously-bypass-approvals-and-sandbox",
46 alias = "yolo",
47 default_value_t = false
48 )]
49 pub dangerously_bypass_approvals_and_sandbox: bool,
50
51 #[arg(long = "dangerously-bypass-hook-trust", default_value_t = false)]
54 pub bypass_hook_trust: bool,
55
56 #[clap(long = "cd", short = 'C', value_name = "DIR")]
58 pub cwd: Option<PathBuf>,
59
60 #[arg(long = "add-dir", value_name = "DIR", value_hint = clap::ValueHint::DirPath)]
62 pub add_dir: Vec<PathBuf>,
63}
64
65impl SharedCliOptions {
66 pub fn inherit_exec_root_options(&mut self, root: &Self) {
67 let self_selected_sandbox_mode =
68 self.sandbox_mode.is_some() || self.dangerously_bypass_approvals_and_sandbox;
69 let Self {
70 images,
71 model,
72 oss,
73 oss_provider,
74 config_profile_v2,
75 sandbox_mode,
76 dangerously_bypass_approvals_and_sandbox,
77 bypass_hook_trust,
78 cwd,
79 add_dir,
80 } = self;
81 let Self {
82 images: root_images,
83 model: root_model,
84 oss: root_oss,
85 oss_provider: root_oss_provider,
86 config_profile_v2: root_config_profile_v2,
87 sandbox_mode: root_sandbox_mode,
88 dangerously_bypass_approvals_and_sandbox: root_dangerously_bypass_approvals_and_sandbox,
89 bypass_hook_trust: root_bypass_hook_trust,
90 cwd: root_cwd,
91 add_dir: root_add_dir,
92 } = root;
93
94 if model.is_none() {
95 model.clone_from(root_model);
96 }
97 if *root_oss {
98 *oss = true;
99 }
100 if oss_provider.is_none() {
101 oss_provider.clone_from(root_oss_provider);
102 }
103 if config_profile_v2.is_none() {
104 config_profile_v2.clone_from(root_config_profile_v2);
105 }
106 if sandbox_mode.is_none() {
107 *sandbox_mode = *root_sandbox_mode;
108 }
109 if !self_selected_sandbox_mode {
110 *dangerously_bypass_approvals_and_sandbox =
111 *root_dangerously_bypass_approvals_and_sandbox;
112 }
113 if !*bypass_hook_trust {
114 *bypass_hook_trust = *root_bypass_hook_trust;
115 }
116 if cwd.is_none() {
117 cwd.clone_from(root_cwd);
118 }
119 if !root_images.is_empty() {
120 let mut merged_images = root_images.clone();
121 merged_images.append(images);
122 *images = merged_images;
123 }
124 if !root_add_dir.is_empty() {
125 let mut merged_add_dir = root_add_dir.clone();
126 merged_add_dir.append(add_dir);
127 *add_dir = merged_add_dir;
128 }
129 }
130
131 pub fn apply_subcommand_overrides(&mut self, subcommand: Self) {
132 let subcommand_selected_sandbox_mode = subcommand.sandbox_mode.is_some()
133 || subcommand.dangerously_bypass_approvals_and_sandbox;
134 let Self {
135 images,
136 model,
137 oss,
138 oss_provider,
139 config_profile_v2,
140 sandbox_mode,
141 dangerously_bypass_approvals_and_sandbox,
142 bypass_hook_trust,
143 cwd,
144 add_dir,
145 } = subcommand;
146
147 if let Some(model) = model {
148 self.model = Some(model);
149 }
150 if oss {
151 self.oss = true;
152 }
153 if let Some(oss_provider) = oss_provider {
154 self.oss_provider = Some(oss_provider);
155 }
156 if let Some(config_profile_v2) = config_profile_v2 {
157 self.config_profile_v2 = Some(config_profile_v2);
158 }
159 if subcommand_selected_sandbox_mode {
160 self.sandbox_mode = sandbox_mode;
161 self.dangerously_bypass_approvals_and_sandbox =
162 dangerously_bypass_approvals_and_sandbox;
163 }
164 if bypass_hook_trust {
165 self.bypass_hook_trust = true;
166 }
167 if let Some(cwd) = cwd {
168 self.cwd = Some(cwd);
169 }
170 if !images.is_empty() {
171 self.images = images;
172 }
173 if !add_dir.is_empty() {
174 self.add_dir.extend(add_dir);
175 }
176 }
177}