tui: remove the voice-input crate feature (#16467)

## Why

`voice-input` is the only remaining TUI crate feature, but it is also a
default feature and nothing in the workspace selects it explicitly. In
practice it is just acting as a proxy for platform support, which is
better expressed with target-specific dependencies and cfgs.

## What changed

- remove the `voice-input` feature from `codex-tui`
- make `cpal` a normal non-Linux target dependency
- replace the feature-based voice and audio cfgs with pure
Linux-vs-non-Linux cfgs
- shrink the workspace-manifest verifier allowlist to remove the
remaining `codex-tui` exception

## How tested

- `python3 .github/scripts/verify_cargo_workspace_manifests.py`
- `cargo test -p codex-tui`
- `just bazel-lock-check`
- `just argument-comment-lint -p codex-tui`
This commit is contained in:
Michael Bolin
2026-04-01 13:03:59 -07:00
committed by GitHub
Unverified
parent d1043ef90e
commit 4d4767f797
6 changed files with 11 additions and 32 deletions
@@ -30,18 +30,8 @@ MANIFEST_FEATURE_EXCEPTIONS = {
"codex-rs/otel/Cargo.toml": {
"disable-default-metrics-exporter": (),
},
"codex-rs/tui/Cargo.toml": {
"default": ("voice-input",),
"voice-input": ("dep:cpal",),
},
}
OPTIONAL_DEPENDENCY_EXCEPTIONS = {
(
"codex-rs/tui/Cargo.toml",
'target.cfg(not(target_os = "linux")).dependencies',
"cpal",
),
}
OPTIONAL_DEPENDENCY_EXCEPTIONS = set()
INTERNAL_DEPENDENCY_FEATURE_EXCEPTIONS = {
(
"codex-rs/core/Cargo.toml",
+1 -5
View File
@@ -17,10 +17,6 @@ path = "src/bin/md-events.rs"
name = "codex_tui"
path = "src/lib.rs"
[features]
default = ["voice-input"]
voice-input = ["dep:cpal"]
[lints]
workspace = true
@@ -112,7 +108,7 @@ codex-windows-sandbox = { workspace = true }
tokio-util = { workspace = true, features = ["time"] }
[target.'cfg(not(target_os = "linux"))'.dependencies]
cpal = { version = "0.15", optional = true }
cpal = "0.15"
[target.'cfg(unix)'.dependencies]
libc = { workspace = true }
+1 -4
View File
@@ -121,10 +121,7 @@ impl AppCommand {
Self(Op::RealtimeConversationStart(params))
}
#[cfg_attr(
any(target_os = "linux", not(feature = "voice-input")),
allow(dead_code)
)]
#[cfg_attr(target_os = "linux", allow(dead_code))]
pub(crate) fn realtime_conversation_audio(params: ConversationAudioParams) -> Self {
Self(Op::RealtimeConversationAudio(params))
}
+1 -4
View File
@@ -313,10 +313,7 @@ pub(crate) enum AppEvent {
},
/// Persist the selected realtime microphone or speaker to top-level config.
#[cfg_attr(
any(target_os = "linux", not(feature = "voice-input")),
allow(dead_code)
)]
#[cfg_attr(target_os = "linux", allow(dead_code))]
PersistRealtimeAudioDeviceSelection {
kind: RealtimeAudioDeviceKind,
name: Option<String>,
+1 -4
View File
@@ -63,10 +63,7 @@ impl AppEventSender {
));
}
#[cfg_attr(
any(target_os = "linux", not(feature = "voice-input")),
allow(dead_code)
)]
#[cfg_attr(target_os = "linux", allow(dead_code))]
pub(crate) fn realtime_conversation_audio(&self, params: ConversationAudioParams) {
self.send(AppEvent::CodexOp(
AppCommand::realtime_conversation_audio(params).into_core(),
+6 -4
View File
@@ -79,9 +79,10 @@ mod app_event;
mod app_event_sender;
mod app_server_session;
mod ascii_animation;
#[cfg(all(not(target_os = "linux"), feature = "voice-input"))]
#[cfg(not(target_os = "linux"))]
mod audio_device;
#[cfg(all(not(target_os = "linux"), not(feature = "voice-input")))]
#[cfg(target_os = "linux")]
#[allow(dead_code)]
mod audio_device {
use crate::app_event::RealtimeAudioDeviceKind;
@@ -151,9 +152,10 @@ pub mod update_action;
mod update_prompt;
mod updates;
mod version;
#[cfg(all(not(target_os = "linux"), feature = "voice-input"))]
#[cfg(not(target_os = "linux"))]
mod voice;
#[cfg(all(not(target_os = "linux"), not(feature = "voice-input")))]
#[cfg(target_os = "linux")]
#[allow(dead_code)]
mod voice {
use crate::app_event_sender::AppEventSender;
use codex_core::config::Config;