diff --git a/codex-rs/cli/src/main.rs b/codex-rs/cli/src/main.rs index 9d278c21228f..8be247bdb4c7 100644 --- a/codex-rs/cli/src/main.rs +++ b/codex-rs/cli/src/main.rs @@ -53,6 +53,9 @@ mod exec_server_telemetry; mod marketplace_cmd; mod mcp_cmd; mod plugin_cmd; +// Keep the proposed privacy CLI schema out of production builds until it is approved. +#[cfg(test)] +mod privacy_cmd; mod remote_control_cmd; #[cfg(target_os = "windows")] mod sandbox_setup; @@ -2825,6 +2828,16 @@ mod tests { ); } + #[test] + fn privacy_subcommand_is_not_registered() { + let command = MultitoolCli::command(); + assert!( + command + .get_subcommands() + .all(|subcommand| subcommand.get_name() != "privacy") + ); + } + fn help_from_args(args: &[&str]) -> String { let err = MultitoolCli::try_parse_from(args).expect_err("help should short-circuit"); assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); diff --git a/codex-rs/cli/src/privacy_cmd.rs b/codex-rs/cli/src/privacy_cmd.rs new file mode 100644 index 000000000000..746247b42f24 --- /dev/null +++ b/codex-rs/cli/src/privacy_cmd.rs @@ -0,0 +1,28 @@ +use std::path::PathBuf; + +use clap::Args; +use clap::Parser; + +#[derive(Debug, Parser)] +#[command(bin_name = "codex privacy")] +pub(crate) struct PrivacyCommand { + #[command(subcommand)] + subcommand: PrivacySubcommand, +} + +#[derive(Debug, clap::Subcommand)] +enum PrivacySubcommand { + /// Export your local Codex data. + Export(PrivacyExportCommand), +} + +#[derive(Debug, Args)] +struct PrivacyExportCommand { + /// Directory to copy the export into. + #[arg(value_name = "PATH")] + output: PathBuf, +} + +#[cfg(test)] +#[path = "privacy_cmd_tests.rs"] +mod tests; diff --git a/codex-rs/cli/src/privacy_cmd_tests.rs b/codex-rs/cli/src/privacy_cmd_tests.rs new file mode 100644 index 000000000000..8eb07c02865c --- /dev/null +++ b/codex-rs/cli/src/privacy_cmd_tests.rs @@ -0,0 +1,35 @@ +use std::path::PathBuf; + +use clap::CommandFactory; +use clap::Parser; +use pretty_assertions::assert_eq; + +use super::PrivacyCommand; +use super::PrivacyExportCommand; +use super::PrivacySubcommand; + +#[test] +fn parses_export_output() { + let PrivacyCommand { + subcommand: PrivacySubcommand::Export(PrivacyExportCommand { output }), + } = PrivacyCommand::try_parse_from(["codex privacy", "export", "out"]).expect("parse"); + + assert_eq!(output, PathBuf::from("out")); +} + +#[test] +fn privacy_help() { + let mut command = PrivacyCommand::command(); + + insta::assert_snapshot!(command.render_long_help().to_string()); +} + +#[test] +fn export_help() { + let mut command = PrivacyCommand::command(); + let export = command + .find_subcommand_mut("export") + .expect("export subcommand"); + + insta::assert_snapshot!(export.render_long_help().to_string()); +} diff --git a/codex-rs/cli/src/snapshots/codex__privacy_cmd__tests__export_help.snap b/codex-rs/cli/src/snapshots/codex__privacy_cmd__tests__export_help.snap new file mode 100644 index 000000000000..7f78484a32c7 --- /dev/null +++ b/codex-rs/cli/src/snapshots/codex__privacy_cmd__tests__export_help.snap @@ -0,0 +1,15 @@ +--- +source: cli/src/privacy_cmd_tests.rs +expression: export.render_long_help().to_string() +--- +Export your local Codex data + +Usage: export + +Arguments: + + Directory to copy the export into + +Options: + -h, --help + Print help diff --git a/codex-rs/cli/src/snapshots/codex__privacy_cmd__tests__privacy_help.snap b/codex-rs/cli/src/snapshots/codex__privacy_cmd__tests__privacy_help.snap new file mode 100644 index 000000000000..065d6ec80290 --- /dev/null +++ b/codex-rs/cli/src/snapshots/codex__privacy_cmd__tests__privacy_help.snap @@ -0,0 +1,13 @@ +--- +source: cli/src/privacy_cmd_tests.rs +expression: command.render_long_help().to_string() +--- +Usage: codex privacy + +Commands: + export Export your local Codex data + help Print this message or the help of the given subcommand(s) + +Options: + -h, --help + Print help