Compare commits

...

2 Commits

Author SHA1 Message Date
Owen Lin
8e9fa727bf update 2026-05-06 17:30:02 -07:00
Owen Lin
9cd26d6fa1 add remote-control command 2026-05-06 15:21:05 -07:00

View File

@@ -130,6 +130,9 @@ enum Subcommand {
/// [experimental] Run the app server or related tooling.
AppServer(AppServerCommand),
/// [experimental] Start a headless app-server with remote control enabled.
RemoteControl,
/// Launch the Codex desktop app (opens the app installer if missing).
#[cfg(any(target_os = "macos", target_os = "windows"))]
App(app_cmd::AppCommand),
@@ -736,6 +739,14 @@ struct FeatureSetArgs {
feature: String,
}
const REMOTE_CONTROL_FEATURE_OVERRIDE: &str = "features.remote_control=true";
fn enable_remote_control_for_invocation(config_overrides: &mut CliConfigOverrides) {
config_overrides
.raw_overrides
.push(REMOTE_CONTROL_FEATURE_OVERRIDE.to_string());
}
fn stage_str(stage: Stage) -> &'static str {
match stage {
Stage::UnderDevelopment => "under development",
@@ -916,6 +927,24 @@ async fn cli_main(arg0_paths: Arg0DispatchPaths) -> anyhow::Result<()> {
}
}
}
Some(Subcommand::RemoteControl) => {
reject_remote_mode_for_subcommand(
root_remote.as_deref(),
root_remote_auth_token_env.as_deref(),
"remote-control",
)?;
enable_remote_control_for_invocation(&mut root_config_overrides);
codex_app_server::run_main_with_transport(
arg0_paths.clone(),
root_config_overrides,
codex_config::LoaderOverrides::default(),
/*default_analytics_enabled*/ false,
codex_app_server::AppServerTransport::Off,
codex_protocol::protocol::SessionSource::Cli,
codex_app_server::AppServerWebsocketAuthSettings::default(),
)
.await?;
}
#[cfg(any(target_os = "macos", target_os = "windows"))]
Some(Subcommand::App(app_cli)) => {
reject_remote_mode_for_subcommand(
@@ -2296,6 +2325,45 @@ mod tests {
assert!(app_server.analytics_default_enabled);
}
#[test]
fn remote_control_override_is_appended_after_root_toggles() {
let mut config_overrides = CliConfigOverrides::default();
config_overrides
.raw_overrides
.push("features.remote_control=false".to_string());
enable_remote_control_for_invocation(&mut config_overrides);
assert_eq!(
config_overrides.raw_overrides,
vec![
"features.remote_control=false".to_string(),
REMOTE_CONTROL_FEATURE_OVERRIDE.to_string(),
]
);
}
#[test]
fn reject_remote_flag_for_remote_control() {
let cli = MultitoolCli::try_parse_from([
"codex",
"--remote",
"ws://127.0.0.1:1234",
"remote-control",
])
.expect("parse");
assert_matches!(cli.subcommand, Some(Subcommand::RemoteControl));
let err = reject_remote_mode_for_subcommand(
cli.remote.remote.as_deref(),
cli.remote.remote_auth_token_env.as_deref(),
"remote-control",
)
.expect_err("remote-control should reject root --remote");
assert!(err.to_string().contains("remote-control"));
}
#[test]
fn remote_flag_parses_for_interactive_root() {
let cli = MultitoolCli::try_parse_from(["codex", "--remote", "ws://127.0.0.1:4500"])