391 lines
8.6 KiB
Rust
391 lines
8.6 KiB
Rust
use std::path::PathBuf;
|
|
|
|
use clap::{Args, Parser, Subcommand};
|
|
|
|
#[derive(Parser)]
|
|
#[command(name = "cdxs", version, about = "Codex Switch CLI")]
|
|
pub struct Cli {
|
|
#[command(subcommand)]
|
|
pub command: Option<Commands>,
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
pub enum Commands {
|
|
/// Login to Codex through OpenAI OAuth.
|
|
Login(LoginArgs),
|
|
/// Import an existing Codex auth file.
|
|
Import(ImportArgs),
|
|
/// List saved accounts.
|
|
List {
|
|
#[arg(long)]
|
|
json: bool,
|
|
#[arg(short, long)]
|
|
force: bool,
|
|
},
|
|
/// List saved accounts without refreshing quota.
|
|
Show {
|
|
#[arg(long)]
|
|
json: bool,
|
|
},
|
|
/// Pull account state from the sync server.
|
|
Pull {
|
|
#[arg(short, long)]
|
|
force: bool,
|
|
},
|
|
/// Push account state to the sync server.
|
|
Push {
|
|
#[arg(short, long)]
|
|
force: bool,
|
|
},
|
|
/// Remove a saved account.
|
|
Remove {
|
|
#[arg(
|
|
value_name = "ACCOUNT_ID_OR_EMAIL",
|
|
help = "Account id, exact email, or email prefix"
|
|
)]
|
|
account: String,
|
|
},
|
|
/// Switch Codex auth.json to a saved account.
|
|
Switch {
|
|
#[arg(
|
|
value_name = "ACCOUNT_ID_OR_EMAIL",
|
|
help = "Account id, exact email, or email prefix"
|
|
)]
|
|
account: Option<String>,
|
|
#[arg(short, long, conflicts_with = "account")]
|
|
auto: bool,
|
|
#[arg(long)]
|
|
codex_home: Option<PathBuf>,
|
|
#[arg(long)]
|
|
apply_fingerprint: bool,
|
|
#[arg(long)]
|
|
model: Option<String>,
|
|
#[arg(long, alias = "reasoning-effort")]
|
|
effort: Option<String>,
|
|
#[arg(long)]
|
|
name: Option<String>,
|
|
},
|
|
/// Prepare auth, set CODEX_HOME, and execute a command.
|
|
Run(RunArgs),
|
|
/// Run a minimal Codex exec to refresh Codex-side quota state.
|
|
Ping(PingArgs),
|
|
/// Refresh and display Codex quota.
|
|
Quota {
|
|
#[arg(value_name = "ACCOUNT_ID_OR_EMAIL")]
|
|
accounts: Vec<String>,
|
|
#[arg(long)]
|
|
json: bool,
|
|
},
|
|
/// Account management commands.
|
|
Account {
|
|
#[command(subcommand)]
|
|
command: AccountCommands,
|
|
},
|
|
/// Managed CODEX_HOME commands.
|
|
Home {
|
|
#[command(subcommand)]
|
|
command: HomeCommands,
|
|
},
|
|
/// Run or manage the cdxs sync server.
|
|
Server {
|
|
#[command(subcommand)]
|
|
command: ServerCommands,
|
|
},
|
|
/// Sync local cdxs.toml with a server.
|
|
Sync {
|
|
#[command(subcommand)]
|
|
command: SyncCommands,
|
|
},
|
|
/// Inspect and manage Codex sessions.
|
|
Session {
|
|
#[command(subcommand)]
|
|
command: SessionCommands,
|
|
},
|
|
}
|
|
|
|
#[derive(Args)]
|
|
pub struct LoginArgs {
|
|
/// Start OpenAI OAuth login for Codex.
|
|
#[command(subcommand)]
|
|
pub command: Option<LoginCommands>,
|
|
/// Add an API key account directly, for example: cdxs login --api sk-...
|
|
#[arg(long, value_name = "KEY")]
|
|
pub api: Option<String>,
|
|
#[arg(long)]
|
|
pub base_url: Option<String>,
|
|
#[arg(long)]
|
|
pub alias: Option<String>,
|
|
#[arg(long)]
|
|
pub model: Option<String>,
|
|
#[arg(long)]
|
|
pub name: Option<String>,
|
|
#[arg(long)]
|
|
pub manual: bool,
|
|
#[arg(long, default_value_t = 1455)]
|
|
pub port: u16,
|
|
#[arg(long)]
|
|
pub switch: bool,
|
|
}
|
|
|
|
#[derive(Args)]
|
|
pub struct ImportArgs {
|
|
/// Import OAuth/API-key auth from auth.json.
|
|
#[command(subcommand)]
|
|
pub command: Option<ImportCommands>,
|
|
#[arg(long)]
|
|
pub file: Option<PathBuf>,
|
|
#[arg(long)]
|
|
pub codex_home: Option<PathBuf>,
|
|
#[arg(long)]
|
|
pub switch: bool,
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
pub enum LoginCommands {
|
|
/// Start OpenAI OAuth login for Codex.
|
|
Oauth {
|
|
#[arg(long)]
|
|
manual: bool,
|
|
#[arg(long, default_value_t = 1455)]
|
|
port: u16,
|
|
#[arg(long)]
|
|
switch: bool,
|
|
},
|
|
/// Add an OpenAI API key account.
|
|
Api {
|
|
#[arg(long)]
|
|
key: String,
|
|
#[arg(long)]
|
|
base_url: Option<String>,
|
|
#[arg(long)]
|
|
alias: Option<String>,
|
|
#[arg(long)]
|
|
model: Option<String>,
|
|
#[arg(long)]
|
|
name: Option<String>,
|
|
#[arg(long)]
|
|
switch: bool,
|
|
},
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
pub enum ImportCommands {
|
|
/// Import OAuth/API-key auth from auth.json.
|
|
Auth {
|
|
#[arg(long)]
|
|
file: Option<PathBuf>,
|
|
#[arg(long)]
|
|
codex_home: Option<PathBuf>,
|
|
#[arg(long)]
|
|
switch: bool,
|
|
},
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
pub enum AccountCommands {
|
|
List {
|
|
#[arg(long)]
|
|
json: bool,
|
|
#[arg(short, long)]
|
|
force: bool,
|
|
},
|
|
Current {
|
|
#[arg(long)]
|
|
json: bool,
|
|
},
|
|
Show {
|
|
account: String,
|
|
#[arg(long)]
|
|
json: bool,
|
|
},
|
|
Remove {
|
|
account: String,
|
|
},
|
|
AddApiKey {
|
|
#[arg(long)]
|
|
key: String,
|
|
#[arg(long)]
|
|
base_url: Option<String>,
|
|
#[arg(long)]
|
|
alias: Option<String>,
|
|
#[arg(long)]
|
|
model: Option<String>,
|
|
#[arg(long)]
|
|
name: Option<String>,
|
|
#[arg(long)]
|
|
switch: bool,
|
|
},
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
pub enum HomeCommands {
|
|
List {
|
|
#[arg(long)]
|
|
json: bool,
|
|
},
|
|
Create {
|
|
name: String,
|
|
#[arg(long)]
|
|
path: PathBuf,
|
|
#[arg(long)]
|
|
account: Option<String>,
|
|
},
|
|
Bind {
|
|
name: String,
|
|
account: String,
|
|
},
|
|
Path {
|
|
name: String,
|
|
},
|
|
Remove {
|
|
name: String,
|
|
},
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
pub enum ServerCommands {
|
|
Run {
|
|
#[arg(long, default_value = "127.0.0.1:8765")]
|
|
bind: String,
|
|
#[arg(long)]
|
|
data_dir: Option<PathBuf>,
|
|
},
|
|
User {
|
|
#[command(subcommand)]
|
|
command: ServerUserCommands,
|
|
},
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
pub enum ServerUserCommands {
|
|
Add {
|
|
username: String,
|
|
#[arg(long)]
|
|
password: String,
|
|
#[arg(long)]
|
|
data_dir: Option<PathBuf>,
|
|
},
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
pub enum SyncCommands {
|
|
Login {
|
|
#[arg(long)]
|
|
server: String,
|
|
#[arg(long)]
|
|
user: String,
|
|
#[arg(long)]
|
|
password: String,
|
|
},
|
|
Pull {
|
|
#[arg(short, long)]
|
|
force: bool,
|
|
},
|
|
Push {
|
|
#[arg(short, long)]
|
|
force: bool,
|
|
},
|
|
Remote {
|
|
#[arg(long)]
|
|
json: bool,
|
|
},
|
|
Status,
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
pub enum SessionCommands {
|
|
/// List Codex sessions from state_5.sqlite.
|
|
List {
|
|
#[arg(long)]
|
|
all_homes: bool,
|
|
#[arg(long)]
|
|
json: bool,
|
|
},
|
|
/// Show token and file statistics for one session.
|
|
Stats {
|
|
session_id: String,
|
|
#[arg(long)]
|
|
all_homes: bool,
|
|
#[arg(long)]
|
|
json: bool,
|
|
},
|
|
/// Move sessions into the cdxs trash and hide them from Codex.
|
|
Trash {
|
|
session_ids: Vec<String>,
|
|
#[arg(long)]
|
|
all_homes: bool,
|
|
},
|
|
/// List sessions stored in cdxs trash.
|
|
TrashList {
|
|
#[arg(long)]
|
|
all_homes: bool,
|
|
#[arg(long)]
|
|
json: bool,
|
|
},
|
|
/// Restore sessions from cdxs trash.
|
|
Restore {
|
|
session_ids: Vec<String>,
|
|
#[arg(long)]
|
|
all_homes: bool,
|
|
},
|
|
/// Check or repair Codex session visibility.
|
|
Visibility {
|
|
#[command(subcommand)]
|
|
command: SessionVisibilityCommands,
|
|
},
|
|
/// Copy missing session threads across managed CODEX_HOME directories.
|
|
SyncThreads {
|
|
#[arg(long)]
|
|
all_homes: bool,
|
|
#[arg(long)]
|
|
dry_run: bool,
|
|
#[arg(long)]
|
|
json: bool,
|
|
},
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
pub enum SessionVisibilityCommands {
|
|
Check {
|
|
#[arg(long)]
|
|
all_homes: bool,
|
|
#[arg(long)]
|
|
json: bool,
|
|
},
|
|
Repair {
|
|
#[arg(long)]
|
|
all_homes: bool,
|
|
#[arg(long)]
|
|
json: bool,
|
|
},
|
|
}
|
|
|
|
#[derive(Args)]
|
|
pub struct RunArgs {
|
|
#[arg(long, conflicts_with = "home")]
|
|
pub account: Option<String>,
|
|
#[arg(long, conflicts_with = "account")]
|
|
pub home: Option<String>,
|
|
#[arg(long)]
|
|
pub codex_home: Option<PathBuf>,
|
|
/// Command after `--`, for example: cdxs run --account me -- codex
|
|
#[arg(required = true, trailing_var_arg = true, allow_hyphen_values = true)]
|
|
pub command: Vec<String>,
|
|
}
|
|
|
|
#[derive(Args)]
|
|
pub struct PingArgs {
|
|
#[arg(long, value_name = "ACCOUNT_ID_OR_EMAIL")]
|
|
pub account: Vec<String>,
|
|
#[arg(long, default_value_t = 5)]
|
|
pub concurrency: usize,
|
|
#[arg(long)]
|
|
pub codex_home: Option<PathBuf>,
|
|
#[arg(long, default_value = "gpt-5.4")]
|
|
pub model: String,
|
|
#[arg(long, default_value = "none")]
|
|
pub reasoning_effort: String,
|
|
#[arg(long, default_value = "hello")]
|
|
pub prompt: String,
|
|
}
|