mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
## Why The app-server no longer needs to expose a TCP websocket listener. Keeping that transport also kept around a separate listener/auth surface that is unnecessary now that local clients can use stdio or the Unix-domain control socket, while remote connectivity is handled by `remote_control`. ## What Changed - Removed `ws://IP:PORT` parsing and the `AppServerTransport::WebSocket` startup path. - Deleted the app-server websocket listener auth module and removed related CLI flags/dependencies. - Kept websocket framing only where it is still needed: over the Unix-domain control socket and in the outbound `remote_control` connection. - Updated app-server CLI/help text and `app-server/README.md` to document only `stdio://`, `unix://`, `unix://PATH`, and `off` for local transports. - Converted affected app-server integration coverage from TCP websocket listeners to UDS-backed websocket connections, and added a parse test that rejects `ws://` listen URLs. - Removed the now-unused workspace `constant_time_eq` dependency and refreshed `Cargo.lock` after `cargo shear` caught the drift. - Moved test app-server UDS socket paths to short Unix temp paths so macOS Bazel test sandboxes do not exceed Unix socket path limits. ## Verification - Added/updated tests around UDS websocket transport behavior and `ws://` listen URL rejection. - `cargo shear` - `cargo metadata --no-deps --format-version 1` - `cargo test -p codex-app-server unix_socket_transport` - `cargo test -p codex-app-server unix_socket_disconnect` - `just fix -p codex-app-server` - `git diff --check` Local full Rust test execution was blocked before compilation by an external fetch failure for the pinned `nornagon/crossterm` git dependency. `just bazel-lock-update` and `just bazel-lock-check` were retried after the manifest cleanup but remain blocked by external BuildBuddy/V8 fetch timeouts.
102 lines
3.3 KiB
Rust
102 lines
3.3 KiB
Rust
use clap::Parser;
|
|
use codex_app_server::AppServerRuntimeOptions;
|
|
use codex_app_server::AppServerTransport;
|
|
use codex_app_server::PluginStartupTasks;
|
|
use codex_app_server::run_main_with_transport_options;
|
|
use codex_arg0::Arg0DispatchPaths;
|
|
use codex_arg0::arg0_dispatch_or_else;
|
|
use codex_config::LoaderOverrides;
|
|
use codex_protocol::protocol::SessionSource;
|
|
use codex_utils_cli::CliConfigOverrides;
|
|
use std::path::PathBuf;
|
|
|
|
// Debug-only test hook: lets integration tests point the server at a temporary
|
|
// managed config file without writing to /etc.
|
|
const MANAGED_CONFIG_PATH_ENV_VAR: &str = "CODEX_APP_SERVER_MANAGED_CONFIG_PATH";
|
|
const DISABLE_MANAGED_CONFIG_ENV_VAR: &str = "CODEX_APP_SERVER_DISABLE_MANAGED_CONFIG";
|
|
|
|
#[derive(Debug, Parser)]
|
|
struct AppServerArgs {
|
|
/// Transport endpoint URL. Supported values: `stdio://` (default),
|
|
/// `unix://`, `unix://PATH`, `off`.
|
|
#[arg(
|
|
long = "listen",
|
|
value_name = "URL",
|
|
default_value = AppServerTransport::DEFAULT_LISTEN_URL
|
|
)]
|
|
listen: AppServerTransport,
|
|
|
|
/// Session source used to derive product restrictions and metadata.
|
|
#[arg(
|
|
long = "session-source",
|
|
value_name = "SOURCE",
|
|
default_value = "vscode",
|
|
value_parser = SessionSource::from_startup_arg
|
|
)]
|
|
session_source: SessionSource,
|
|
|
|
/// Hidden debug-only test hook used by integration tests that spawn the
|
|
/// production app-server binary.
|
|
#[cfg(debug_assertions)]
|
|
#[arg(long = "disable-plugin-startup-tasks-for-tests", hide = true)]
|
|
disable_plugin_startup_tasks_for_tests: bool,
|
|
}
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
arg0_dispatch_or_else(|arg0_paths: Arg0DispatchPaths| async move {
|
|
let args = AppServerArgs::parse();
|
|
let loader_overrides = if disable_managed_config_from_debug_env() {
|
|
LoaderOverrides::without_managed_config_for_tests()
|
|
} else {
|
|
managed_config_path_from_debug_env()
|
|
.map(LoaderOverrides::with_managed_config_path_for_tests)
|
|
.unwrap_or_default()
|
|
};
|
|
let transport = args.listen;
|
|
let session_source = args.session_source;
|
|
let mut runtime_options = AppServerRuntimeOptions::default();
|
|
#[cfg(debug_assertions)]
|
|
if args.disable_plugin_startup_tasks_for_tests {
|
|
runtime_options.plugin_startup_tasks = PluginStartupTasks::Skip;
|
|
}
|
|
|
|
run_main_with_transport_options(
|
|
arg0_paths,
|
|
CliConfigOverrides::default(),
|
|
loader_overrides,
|
|
/*default_analytics_enabled*/ false,
|
|
transport,
|
|
session_source,
|
|
runtime_options,
|
|
)
|
|
.await?;
|
|
Ok(())
|
|
})
|
|
}
|
|
|
|
fn disable_managed_config_from_debug_env() -> bool {
|
|
#[cfg(debug_assertions)]
|
|
{
|
|
if let Ok(value) = std::env::var(DISABLE_MANAGED_CONFIG_ENV_VAR) {
|
|
return matches!(value.as_str(), "1" | "true" | "TRUE" | "yes" | "YES");
|
|
}
|
|
}
|
|
|
|
false
|
|
}
|
|
|
|
fn managed_config_path_from_debug_env() -> Option<PathBuf> {
|
|
#[cfg(debug_assertions)]
|
|
{
|
|
if let Ok(value) = std::env::var(MANAGED_CONFIG_PATH_ENV_VAR) {
|
|
return if value.is_empty() {
|
|
None
|
|
} else {
|
|
Some(PathBuf::from(value))
|
|
};
|
|
}
|
|
}
|
|
|
|
None
|
|
}
|