Skip to content

Commit 20982d5

Browse files
fix(app-server) move windows world writable warning (#6916)
## Summary Move the app-server warning into the process_new_conversation ## Testing - [x] Tested locally
1 parent 64ae9aa commit 20982d5

File tree

2 files changed

+69
-60
lines changed

2 files changed

+69
-60
lines changed

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

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ use codex_app_server_protocol::TurnStatus;
9191
use codex_app_server_protocol::UserInfoResponse;
9292
use codex_app_server_protocol::UserInput as V2UserInput;
9393
use codex_app_server_protocol::UserSavedConfig;
94+
use codex_app_server_protocol::WindowsWorldWritableWarningNotification;
9495
use codex_app_server_protocol::build_turns_from_event_msgs;
9596
use codex_backend_client::Client as BackendClient;
9697
use codex_core::AuthManager;
@@ -1239,7 +1240,7 @@ impl CodexMessageProcessor {
12391240
let overrides = ConfigOverrides {
12401241
model,
12411242
config_profile: profile,
1242-
cwd: cwd.map(PathBuf::from),
1243+
cwd: cwd.clone().map(PathBuf::from),
12431244
approval_policy,
12441245
sandbox_mode,
12451246
model_provider,
@@ -1254,7 +1255,7 @@ impl CodexMessageProcessor {
12541255
// Persist windows sandbox feature.
12551256
// TODO: persist default config in general.
12561257
let mut cli_overrides = cli_overrides.unwrap_or_default();
1257-
if cfg!(target_os = "windows") && self.config.features.enabled(Feature::WindowsSandbox) {
1258+
if cfg!(windows) && self.config.features.enabled(Feature::WindowsSandbox) {
12581259
cli_overrides.insert(
12591260
"features.enable_experimental_windows_sandbox".to_string(),
12601261
serde_json::json!(true),
@@ -1273,6 +1274,10 @@ impl CodexMessageProcessor {
12731274
return;
12741275
}
12751276
};
1277+
if cfg!(windows) && config.features.enabled(Feature::WindowsSandbox) {
1278+
self.handle_windows_world_writable_warning(config.cwd.clone())
1279+
.await;
1280+
}
12761281

12771282
match self.conversation_manager.new_conversation(config).await {
12781283
Ok(conversation_id) => {
@@ -1953,6 +1958,15 @@ impl CodexMessageProcessor {
19531958
include_apply_patch_tool,
19541959
} = overrides;
19551960

1961+
// Persist windows sandbox feature.
1962+
let mut cli_overrides = cli_overrides.unwrap_or_default();
1963+
if cfg!(windows) && self.config.features.enabled(Feature::WindowsSandbox) {
1964+
cli_overrides.insert(
1965+
"features.enable_experimental_windows_sandbox".to_string(),
1966+
serde_json::json!(true),
1967+
);
1968+
}
1969+
19561970
let overrides = ConfigOverrides {
19571971
model,
19581972
config_profile: profile,
@@ -1968,7 +1982,7 @@ impl CodexMessageProcessor {
19681982
..Default::default()
19691983
};
19701984

1971-
derive_config_from_params(overrides, cli_overrides).await
1985+
derive_config_from_params(overrides, Some(cli_overrides)).await
19721986
}
19731987
None => Ok(self.config.as_ref().clone()),
19741988
};
@@ -1983,6 +1997,10 @@ impl CodexMessageProcessor {
19831997
return;
19841998
}
19851999
};
2000+
if cfg!(windows) && config.features.enabled(Feature::WindowsSandbox) {
2001+
self.handle_windows_world_writable_warning(config.cwd.clone())
2002+
.await;
2003+
}
19862004

19872005
let conversation_history = if let Some(path) = path {
19882006
match RolloutRecorder::get_rollout_history(&path).await {
@@ -2841,6 +2859,53 @@ impl CodexMessageProcessor {
28412859
Err(_) => None,
28422860
}
28432861
}
2862+
2863+
/// On Windows, when using the experimental sandbox, we need to warn the user about world-writable directories.
2864+
async fn handle_windows_world_writable_warning(&self, cwd: PathBuf) {
2865+
if !cfg!(windows) {
2866+
return;
2867+
}
2868+
2869+
if !self.config.features.enabled(Feature::WindowsSandbox) {
2870+
return;
2871+
}
2872+
2873+
if !matches!(
2874+
self.config.sandbox_policy,
2875+
codex_protocol::protocol::SandboxPolicy::WorkspaceWrite { .. }
2876+
| codex_protocol::protocol::SandboxPolicy::ReadOnly
2877+
) {
2878+
return;
2879+
}
2880+
2881+
if self
2882+
.config
2883+
.notices
2884+
.hide_world_writable_warning
2885+
.unwrap_or(false)
2886+
{
2887+
return;
2888+
}
2889+
2890+
// This function is stubbed out to return None on non-Windows platforms
2891+
if let Some((sample_paths, extra_count, failed_scan)) =
2892+
codex_windows_sandbox::world_writable_warning_details(
2893+
self.config.codex_home.as_path(),
2894+
cwd,
2895+
)
2896+
{
2897+
tracing::warn!("world writable warning: {sample_paths:?} {extra_count} {failed_scan}");
2898+
self.outgoing
2899+
.send_server_notification(ServerNotification::WindowsWorldWritableWarning(
2900+
WindowsWorldWritableWarningNotification {
2901+
sample_paths,
2902+
extra_count,
2903+
failed_scan,
2904+
},
2905+
))
2906+
.await;
2907+
}
2908+
}
28442909
}
28452910

28462911
async fn derive_config_from_params(

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

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,18 @@ use codex_app_server_protocol::JSONRPCErrorError;
1111
use codex_app_server_protocol::JSONRPCNotification;
1212
use codex_app_server_protocol::JSONRPCRequest;
1313
use codex_app_server_protocol::JSONRPCResponse;
14-
use codex_app_server_protocol::ServerNotification;
15-
use codex_app_server_protocol::WindowsWorldWritableWarningNotification;
1614
use codex_core::AuthManager;
1715
use codex_core::ConversationManager;
1816
use codex_core::config::Config;
1917
use codex_core::default_client::USER_AGENT_SUFFIX;
2018
use codex_core::default_client::get_codex_user_agent;
21-
use codex_core::features::Feature;
2219
use codex_feedback::CodexFeedback;
2320
use codex_protocol::protocol::SessionSource;
2421
use std::sync::Arc;
2522

2623
pub(crate) struct MessageProcessor {
2724
outgoing: Arc<OutgoingMessageSender>,
2825
codex_message_processor: CodexMessageProcessor,
29-
config: Arc<Config>,
3026
initialized: bool,
3127
}
3228

@@ -54,14 +50,13 @@ impl MessageProcessor {
5450
conversation_manager,
5551
outgoing.clone(),
5652
codex_linux_sandbox_exe,
57-
config.clone(),
53+
config,
5854
feedback,
5955
);
6056

6157
Self {
6258
outgoing,
6359
codex_message_processor,
64-
config,
6560
initialized: false,
6661
}
6762
}
@@ -122,7 +117,6 @@ impl MessageProcessor {
122117
self.outgoing.send_response(request_id, response).await;
123118

124119
self.initialized = true;
125-
self.handle_windows_world_writable_warning().await;
126120

127121
return;
128122
}
@@ -162,54 +156,4 @@ impl MessageProcessor {
162156
pub(crate) fn process_error(&mut self, err: JSONRPCError) {
163157
tracing::error!("<- error: {:?}", err);
164158
}
165-
166-
/// On Windows, when using the experimental sandbox, we need to warn the user about world-writable directories.
167-
async fn handle_windows_world_writable_warning(&self) {
168-
if !cfg!(windows) {
169-
return;
170-
}
171-
172-
if !self.config.features.enabled(Feature::WindowsSandbox) {
173-
return;
174-
}
175-
176-
if !matches!(
177-
self.config.sandbox_policy,
178-
codex_protocol::protocol::SandboxPolicy::WorkspaceWrite { .. }
179-
| codex_protocol::protocol::SandboxPolicy::ReadOnly
180-
) {
181-
return;
182-
}
183-
184-
if self
185-
.config
186-
.notices
187-
.hide_world_writable_warning
188-
.unwrap_or(false)
189-
{
190-
return;
191-
}
192-
193-
// This function is stubbed out to return None on non-Windows platforms
194-
let cwd = match std::env::current_dir() {
195-
Ok(cwd) => cwd,
196-
Err(_) => return,
197-
};
198-
if let Some((sample_paths, extra_count, failed_scan)) =
199-
codex_windows_sandbox::world_writable_warning_details(
200-
self.config.codex_home.as_path(),
201-
cwd,
202-
)
203-
{
204-
self.outgoing
205-
.send_server_notification(ServerNotification::WindowsWorldWritableWarning(
206-
WindowsWorldWritableWarningNotification {
207-
sample_paths,
208-
extra_count,
209-
failed_scan,
210-
},
211-
))
212-
.await;
213-
}
214-
}
215159
}

0 commit comments

Comments
 (0)