Skip to content

Commit a48cafb

Browse files
CSResselnori-agentclaude
authored
feat(cli): Add feature flags for modular CLI builds (#93)
## Summary 🤖 Generated with [Nori](https://www.npmjs.com/package/nori-ai) - Implemented Cargo feature flags to make the CLI binary modular with `default = []` (minimal) and `full` (complete) configurations - Made 6 dependencies optional: `codex-app-server`, `codex-chatgpt`, `codex-cloud-tasks`, `codex-login`, `codex-mcp-server`, `codex-responses-api-proxy`, `codex-rmcp-client` - Added `#[cfg(feature = "...")]` guards throughout `main.rs` for conditional compilation - Achieves 22% release binary size reduction (46MB → 36MB) for minimal builds ## Test Plan - [x] `cargo build -p codex-cli` (minimal) compiles successfully - [x] `cargo build -p codex-cli --features full` compiles successfully - [x] `cargo test --all --features full` passes - [x] `cargo clippy --all --features full` passes - [x] MCP integration tests correctly skipped without `mcp-server` feature Share Nori with your team: https://www.npmjs.com/package/nori-ai --------- Co-authored-by: Nori <contact@tilework.tech> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent a441e4e commit a48cafb

30 files changed

Lines changed: 1303 additions & 63 deletions

codex-rs/Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codex-rs/cli/Cargo.toml

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,74 @@ path = "src/lib.rs"
1515
[lints]
1616
workspace = true
1717

18+
[features]
19+
default = []
20+
21+
# Full feature set - enables all legacy functionality
22+
full = [
23+
"app-server",
24+
"cloud-tasks",
25+
"login",
26+
"feedback",
27+
"backend-client",
28+
"upstream-updates",
29+
"mcp-server",
30+
"chatgpt",
31+
"responses-api-proxy",
32+
"oss-providers",
33+
]
34+
35+
# App server functionality
36+
app-server = ["dep:codex-app-server"]
37+
38+
# Cloud tasks command
39+
cloud-tasks = ["dep:codex-cloud-tasks"]
40+
41+
# Login/logout commands - propagate to TUI
42+
login = ["dep:codex-login", "codex-tui/login"]
43+
44+
# Feedback feature - propagate to TUI (legacy OpenAI Sentry feedback)
45+
# Future Nori feedback: https://github.com/tilework-tech/nori-cli/issues
46+
feedback = ["codex-tui/feedback"]
47+
48+
# Backend client feature - propagate to TUI
49+
backend-client = ["codex-tui/backend-client"]
50+
51+
# Upstream updates feature - propagate to TUI
52+
upstream-updates = ["codex-tui/upstream-updates"]
53+
54+
# OSS providers (Ollama, LM Studio) - propagate to TUI and codex-common
55+
oss-providers = ["codex-tui/oss-providers", "codex-common/oss-providers"]
56+
57+
# MCP server functionality
58+
mcp-server = ["dep:codex-mcp-server", "dep:codex-rmcp-client"]
59+
60+
# ChatGPT/apply command
61+
chatgpt = ["dep:codex-chatgpt"]
62+
63+
# Responses API proxy
64+
responses-api-proxy = ["dep:codex-responses-api-proxy"]
65+
1866
[dependencies]
1967
anyhow = { workspace = true }
2068
clap = { workspace = true, features = ["derive"] }
2169
clap_complete = { workspace = true }
2270
codex-acp = { workspace = true }
23-
codex-app-server = { workspace = true }
71+
codex-app-server = { workspace = true, optional = true }
2472
codex-app-server-protocol = { workspace = true }
2573
codex-arg0 = { workspace = true }
26-
codex-chatgpt = { workspace = true }
27-
codex-cloud-tasks = { path = "../cloud-tasks" }
74+
codex-chatgpt = { workspace = true, optional = true }
75+
codex-cloud-tasks = { path = "../cloud-tasks", optional = true }
2876
codex-common = { workspace = true, features = ["cli"] }
2977
codex-core = { workspace = true }
3078
codex-exec = { workspace = true }
3179
codex-execpolicy = { workspace = true }
32-
codex-login = { workspace = true }
33-
codex-mcp-server = { workspace = true }
80+
codex-login = { workspace = true, optional = true }
81+
codex-mcp-server = { workspace = true, optional = true }
3482
codex-process-hardening = { workspace = true }
3583
codex-protocol = { workspace = true }
36-
codex-responses-api-proxy = { workspace = true }
37-
codex-rmcp-client = { workspace = true }
84+
codex-responses-api-proxy = { workspace = true, optional = true }
85+
codex-rmcp-client = { workspace = true, optional = true }
3886
codex-stdio-to-uds = { workspace = true }
3987
codex-tui = { workspace = true }
4088
ctor = { workspace = true }
@@ -62,3 +110,12 @@ assert_matches = { workspace = true }
62110
predicates = { workspace = true }
63111
pretty_assertions = { workspace = true }
64112
tempfile = { workspace = true }
113+
114+
# Integration tests that require the mcp-server feature
115+
[[test]]
116+
name = "mcp_add_remove"
117+
required-features = ["mcp-server"]
118+
119+
[[test]]
120+
name = "mcp_list"
121+
required-features = ["mcp-server"]

codex-rs/cli/docs.md

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,8 @@ The `codex-cli` crate is the main multitool binary that provides the `codex` com
1010

1111
This crate is the primary entry point that ties together all other crates:
1212

13-
- **Dispatches to** `codex-tui` for interactive mode (default, no subcommand)
14-
- **Dispatches to** `codex-exec` for `codex exec` non-interactive execution
15-
- **Dispatches to** `codex-mcp-server` for `codex mcp-server`
16-
- **Dispatches to** `codex-app-server` for `codex app-server`
17-
- **Dispatches to** `codex-cloud-tasks` for `codex cloud` browsing
18-
- **Uses** `codex-login` for authentication flows
19-
- **Uses** `codex-chatgpt` for the `codex apply` command
13+
- **Always included:** `codex-tui`, `codex-exec`, `codex-acp`, `codex-core` (minimal build)
14+
- **Optional via features:** `codex-mcp-server`, `codex-app-server`, `codex-cloud-tasks`, `codex-login`, `codex-chatgpt`, `codex-responses-api-proxy`
2015
- **Uses** `codex-arg0` for arg0-based dispatch (Linux sandbox embedding)
2116

2217
### Core Implementation
@@ -38,20 +33,20 @@ match subcommand {
3833

3934
**Subcommands:**
4035

41-
| Subcommand | Alias | Description |
42-
|------------|-------|-------------|
43-
| `exec` | `e` | Run Codex non-interactively |
44-
| `login` | | Manage authentication |
45-
| `logout` | | Remove stored credentials |
46-
| `mcp` | | Manage MCP server configurations |
47-
| `mcp-server` | | Run as MCP server (stdio) |
48-
| `app-server` | | Run app server (JSON-RPC stdio) |
49-
| `resume` | | Resume previous session |
50-
| `apply` | `a` | Apply latest Codex diff to working tree |
51-
| `sandbox` | `debug` | Test sandbox enforcement |
52-
| `cloud` | | Browse Codex Cloud tasks |
53-
| `completion` | | Generate shell completions |
54-
| `features` | | List feature flags |
36+
| Subcommand | Alias | Description | Required Feature |
37+
|------------|-------|-------------|------------------|
38+
| `exec` | `e` | Run Codex non-interactively | (always) |
39+
| `login` | | Manage authentication | `login` |
40+
| `logout` | | Remove stored credentials | `login` |
41+
| `mcp` | | Manage MCP server configurations | `mcp-server` |
42+
| `mcp-server` | | Run as MCP server (stdio) | `mcp-server` |
43+
| `app-server` | | Run app server (JSON-RPC stdio) | `app-server` |
44+
| `resume` | | Resume previous session | (always) |
45+
| `apply` | `a` | Apply latest Codex diff to working tree | `chatgpt` |
46+
| `sandbox` | `debug` | Test sandbox enforcement | (always) |
47+
| `cloud` | | Browse Codex Cloud tasks | `cloud-tasks` |
48+
| `completion` | | Generate shell completions | (always) |
49+
| `features` | | List feature flags | (always) |
5550

5651
**Feature Toggles:**
5752

@@ -71,6 +66,44 @@ These translate to `-c features.<name>=true/false` config overrides.
7166

7267
### Things to Know
7368

69+
**Cargo Feature Flags (Compile-time):**
70+
71+
The CLI uses Cargo features to enable optional functionality. By default (`default = []`), only core functionality is included (TUI, exec, ACP). Optional features can be enabled individually or via the `full` meta-feature:
72+
73+
| Feature | Dependencies | Enables |
74+
|---------|--------------|---------|
75+
| `full` | All features | Complete legacy binary |
76+
| `app-server` | `codex-app-server` | `app-server` subcommand |
77+
| `cloud-tasks` | `codex-cloud-tasks` | `cloud` subcommand |
78+
| `login` | `codex-login`, `codex-tui/login` | `login`/`logout` subcommands + TUI login |
79+
| `feedback` | `codex-tui/feedback` | Sentry feedback in TUI |
80+
| `backend-client` | `codex-tui/backend-client` | Cloud tasks backend client |
81+
| `upstream-updates` | `codex-tui/upstream-updates` | OpenAI update mechanism (vs Nori's) |
82+
| `mcp-server` | `codex-mcp-server`, `codex-rmcp-client` | `mcp`, `mcp-server` subcommands |
83+
| `chatgpt` | `codex-chatgpt` | `apply` subcommand |
84+
| `responses-api-proxy` | `codex-responses-api-proxy` | `responses-api-proxy` subcommand |
85+
| `oss-providers` | `codex-tui/oss-providers`, `codex-common/oss-providers` | Ollama/LM Studio local model support |
86+
87+
**Feature Propagation to TUI:**
88+
89+
Several CLI features propagate to the TUI crate for coordinated behavior:
90+
- `login` -> `codex-tui/login`: Enables login screens and `/login` command in TUI
91+
- `feedback` -> `codex-tui/feedback`: Enables Sentry feedback and `/feedback` command
92+
- `backend-client` -> `codex-tui/backend-client`: Enables cloud tasks backend
93+
- `upstream-updates` -> `codex-tui/upstream-updates`: Uses OpenAI update system instead of Nori's
94+
- `oss-providers` -> `codex-tui/oss-providers` -> `codex-common/oss-providers`: Enables Ollama/LM Studio local model support
95+
96+
Without these features, the TUI uses Nori-specific alternatives (e.g., GitHub Discussions for feedback, GitHub releases for updates). For OSS providers, the `codex-common` crate provides stub implementations that return `None` or errors when the feature is disabled.
97+
98+
Build examples:
99+
```bash
100+
cargo build -p codex-cli # Minimal (TUI + exec + ACP only, Nori updates)
101+
cargo build -p codex-cli --features full # All functionality (OpenAI-compatible)
102+
cargo build -p codex-cli --features login,mcp-server # Selective
103+
```
104+
105+
Feature-gated code uses `#[cfg(feature = "...")]` on imports, enum variants, match arms, and struct definitions in `main.rs`. Integration tests that require specific features use `required-features` in `Cargo.toml` (e.g., MCP tests require `mcp-server`).
106+
74107
**Sandbox Debugging:**
75108

76109
The `debug_sandbox` module (in `debug_sandbox/`) provides:

codex-rs/cli/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod debug_sandbox;
22
mod exit_status;
3+
#[cfg(feature = "login")]
34
pub mod login;
45

56
use clap::Parser;

0 commit comments

Comments
 (0)