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
betamodule.
Two modules are involved, by design:
cli/flox/src/beta/— owns the args struct andhandle()body, plus any supporting logic. 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/flox/src/beta/<snake_name>.rs. Mirrorcli/flox/src/beta/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 incommands/beta.rs. 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/flox/src/beta/mod.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 module 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. - Reaching into the rest of the
floxcrate (crate::utils::message,crate::utils::events, …) is fine and needs no factoring out. Prefer it over duplicating a helper insidebeta/. - Telemetry: beta commands go through the normal dispatcher, so
cli.command_runandcli.command_completedare emitted for free — most beta commands need no instrumentation of their own. Add a bespoke v2 event (see theadding-metrics-eventsskill) only when there is domain data worth reporting; that touchescli/flox-eventsand is reviewed as a wire-contract change, so the keep-flox-rust-sdk-unchanged guidance above doesn't make it free. Don't add newsubcommand_metric!calls — the existing beta commands that use the macro predate the v2 pipeline; don't copy them. Event names are frozen once a release that can emit them ships, gated or not. - Don't put beta-only logic in
commands/, elsewhere inflox, or inflox-rust-sdk; keep it in thebetamodule. - Integration tests are not required for beta commands while they remain gated.
- Tests for beta code are skipped by default while the subsystem is
gated:
cli/tests/extension.batsskips every test fromsetup(), and unit tests undercli/flox/src/beta/sit behind the off-by-defaultbeta-testscargo feature (gate newmod testswith#[cfg(feature = "beta-tests")]). Run them while hacking withcargo test -p flox --features beta-tests beta::.