name: adding-beta-subcommand
description: Use when adding a new beta CLI subcommand to flox, which could also be called an experimental or unstable subcommand. This should be used when adding a command to the beta crate that respects the beta feature flag.
Adding a new beta subcommand
Beta subcommands are top-level flox <name> commands. The
Commands::Beta arm in cli/flox/src/commands/mod.rs checks
flox.features.beta once before dispatching, so individual handlers shouldn't
re-check it.
When not to use this skill
- Adding a subcommand under an existing top-level command (e.g.
flox build subcommand). This skill is only for new top-levelflox <name>commands gated byfeatures.beta. - Promoting a beta command to stable — that's a separate move out of
the
betacrate.
Two crates are involved, by design:
cli/beta— owns the args struct andhandle()body. Plain bpaf-derived structs; nocommandorhideattributes.cli/flox/src/commands/beta.rs— owns theBetaCommandsenum where the command name,hide, and dispatch live. This is the reviewed surface that enforces beta commands stay hidden fromflox --help.
Steps
Create the args + handler in
cli/beta/src/<snake_name>.rs. Mirrorcli/beta/src/beta_enabled.rs:#[derive(Bpaf, Clone, Debug)]struct holding any options/args.- No
#[bpaf(command(...))]and no#[bpaf(hide)]on the struct. Those attributes live on the variant in the CLI crate. pub async fn handle(self, flox: Flox) -> Result<()>with#[instrument(name = "<command-name>", skip_all)].- Do not check
flox.features.beta— already gated in the CLI.
Register the module in
cli/beta/src/lib.rs:pub mod <snake_name>;Wire up the command in
cli/flox/src/commands/beta.rs:Add a variant to
BetaCommands. Usecommand("<kebab-name>")and always includehideon the enum variant#[bpaf(hide)]is not sufficient on its own; without per-varianthidethe subcommand leaks intoflox --help. (Verify with the check in step 4.)#[bpaf(command("<kebab-name>"), hide)] <CamelName>(#[bpaf(external(<snake_name>::<snake_name>))] <snake_name>::<CamelName>),Add a match arm to
BetaCommands::handle:BetaCommands::<CamelName>(args) => args.handle(flox).await,
Verify, inside a worktree (per the repo
AGENTS.md) and insidenix develop(or wrap each command withnix develop -cif not already in the shell —cargoand friends are not on bare PATH):cargo build -p flox./target/debug/flox <kebab-name>→ exits non-zero with:Enable beta features to run this command: flox config --set features.beta trueFLOX_FEATURES_BETA=true ./target/debug/flox <kebab-name>→ runs the handler../target/debug/flox --help→ the new command must not appear. If it does,hideis missing from the variant.
Conventions
- Beta commands may freely depend on
flox-rust-sdk, but when adding beta commands, strive to leaveflox-rust-sdkcode unchanged. Any code in the beta crate doesn't need to be reviewed for stability, but any code changes in other crates will require more thorough review which will make it slower to add the beta command. - If we need to share code between
betaandfloxcrates, we may need to factor it out to avoid a cyclic dependency. Note that this will increase review burden. - Don't put beta-only logic in
floxorflox-rust-sdk; keep it in thebetacrate. - Integration tests are not required for beta commands while they remain gated.