mirror of
https://github.com/openai/codex.git
synced 2026-04-28 02:11:08 +03:00
This changes how instantiating `Config` works and also adds `approval_policy` and `sandbox_policy` as fields. The idea is: * All fields of `Config` have appropriate default values. * `Config` is initially loaded from `~/.codex/config.toml`, so values in `config.toml` will override those defaults. * Clients must instantiate `Config` via `Config::load_with_overrides(ConfigOverrides)` where `ConfigOverrides` has optional overrides that are expected to be settable based on CLI flags. The `Config` should be defined early in the program and then passed down. Now functions like `init_codex()` take fewer individual parameters because they can just take a `Config`. Also, `Config::load()` used to fail silently if `~/.codex/config.toml` had a parse error and fell back to the default config. This seemed really bad because it wasn't clear why the values in my `config.toml` weren't getting picked up. I changed things so that `load_with_overrides()` returns `Result<Config>` and verified that the various CLIs print a reasonable error if `config.toml` is malformed. Finally, I also updated the TUI to show which **sandbox** value is being used, as we do for other key values like **model** and **approval**. This was also a reminder that the various values of `--sandbox` are honored on Linux but not macOS today, so I added some TODOs about fixing that.
119 lines
2.9 KiB
Rust
119 lines
2.9 KiB
Rust
mod proto;
|
||
mod seatbelt;
|
||
|
||
use std::path::PathBuf;
|
||
|
||
use clap::ArgAction;
|
||
use clap::Parser;
|
||
use codex_core::SandboxModeCliArg;
|
||
use codex_exec::Cli as ExecCli;
|
||
use codex_interactive::Cli as InteractiveCli;
|
||
use codex_repl::Cli as ReplCli;
|
||
use codex_tui::Cli as TuiCli;
|
||
|
||
use crate::proto::ProtoCli;
|
||
|
||
/// Codex CLI
|
||
///
|
||
/// If no subcommand is specified, options will be forwarded to the interactive CLI.
|
||
#[derive(Debug, Parser)]
|
||
#[clap(
|
||
author,
|
||
version,
|
||
// If a sub‑command is given, ignore requirements of the default args.
|
||
subcommand_negates_reqs = true
|
||
)]
|
||
struct MultitoolCli {
|
||
#[clap(flatten)]
|
||
interactive: InteractiveCli,
|
||
|
||
#[clap(subcommand)]
|
||
subcommand: Option<Subcommand>,
|
||
}
|
||
|
||
#[derive(Debug, clap::Subcommand)]
|
||
enum Subcommand {
|
||
/// Run Codex non-interactively.
|
||
#[clap(visible_alias = "e")]
|
||
Exec(ExecCli),
|
||
|
||
/// Run the TUI.
|
||
#[clap(visible_alias = "t")]
|
||
Tui(TuiCli),
|
||
|
||
/// Run the REPL.
|
||
#[clap(visible_alias = "r")]
|
||
Repl(ReplCli),
|
||
|
||
/// Run the Protocol stream via stdin/stdout
|
||
#[clap(visible_alias = "p")]
|
||
Proto(ProtoCli),
|
||
|
||
/// Internal debugging commands.
|
||
Debug(DebugArgs),
|
||
}
|
||
|
||
#[derive(Debug, Parser)]
|
||
struct DebugArgs {
|
||
#[command(subcommand)]
|
||
cmd: DebugCommand,
|
||
}
|
||
|
||
#[derive(Debug, clap::Subcommand)]
|
||
enum DebugCommand {
|
||
/// Run a command under Seatbelt (macOS only).
|
||
Seatbelt(SeatbeltCommand),
|
||
}
|
||
|
||
#[derive(Debug, Parser)]
|
||
struct SeatbeltCommand {
|
||
/// Writable folder for sandbox in full-auto mode (can be specified multiple times).
|
||
#[arg(long = "writable-root", short = 'w', value_name = "DIR", action = ArgAction::Append, use_value_delimiter = false)]
|
||
writable_roots: Vec<PathBuf>,
|
||
|
||
/// Configure the process restrictions for the command.
|
||
#[arg(long = "sandbox", short = 's')]
|
||
sandbox_policy: SandboxModeCliArg,
|
||
|
||
/// Full command args to run under seatbelt.
|
||
#[arg(trailing_var_arg = true)]
|
||
command: Vec<String>,
|
||
}
|
||
|
||
#[derive(Debug, Parser)]
|
||
struct ReplProto {}
|
||
|
||
#[tokio::main]
|
||
async fn main() -> anyhow::Result<()> {
|
||
let cli = MultitoolCli::parse();
|
||
|
||
match cli.subcommand {
|
||
None => {
|
||
codex_interactive::run_main(cli.interactive).await?;
|
||
}
|
||
Some(Subcommand::Exec(exec_cli)) => {
|
||
codex_exec::run_main(exec_cli).await?;
|
||
}
|
||
Some(Subcommand::Tui(tui_cli)) => {
|
||
codex_tui::run_main(tui_cli)?;
|
||
}
|
||
Some(Subcommand::Repl(repl_cli)) => {
|
||
codex_repl::run_main(repl_cli).await?;
|
||
}
|
||
Some(Subcommand::Proto(proto_cli)) => {
|
||
proto::run_main(proto_cli).await?;
|
||
}
|
||
Some(Subcommand::Debug(debug_args)) => match debug_args.cmd {
|
||
DebugCommand::Seatbelt(SeatbeltCommand {
|
||
command,
|
||
sandbox_policy,
|
||
writable_roots,
|
||
}) => {
|
||
seatbelt::run_seatbelt(command, sandbox_policy.into(), writable_roots).await?;
|
||
}
|
||
},
|
||
}
|
||
|
||
Ok(())
|
||
}
|