Repository navigation
feat(cli): pick a missing organization, environment, or wallet - #22
Conversation
9540228 to
6c29564
Compare
6c29564 to
33efa27
Compare
33efa27 to
069b2d5
Compare
1a065cb to
37e9bc5
Compare
37e9bc5 to
f5b085e
Compare
f5b085e to
7e7814c
Compare
tee8z
left a comment
There was a problem hiding this comment.
Review against docs/quality.md, with the CRAP report (scripts/crap-report.sh) run on this head.
ask fails the CRAP budget: 28.30 (cyclomatic 13, 55.1% coverage). It is the only function over 20 in the crate. The branching is fine: a straight sequence of early returns with nesting depth 1. The problem is that no test runs the organization and environment pickers with a browser login (src/pick.rs:123-151). The quality guide says to add meaningful tests rather than split functions, so these suggestions add tests:
- Login, organization then environment:
profiles createpicks both.environments listpicks only the organization. - API key with
--orgbut no--env: shows the environments notice. - Empty wallet list: "No wallets to choose from."
To drive two pickers in one run, on_a_terminal now takes (prompt, keys) steps instead of Option<prompt> plus keys. The suggestions also drop the empty-list check in Terminal::pick, which can never run because choose returns first.
Apply them all as one batch (Files changed → "Add suggestion to batch" on each). The call-site suggestions only compile with the new on_a_terminal signature.
With all suggestions applied, I ran:
cargo fmt --checkandcargo clippy --locked --all-targets -- -D warnings: clean.cargo test --locked: 92 unit and 65 integration tests pass.- CRAP report:
askis 13.01 (95.9% coverage),fill11.00 (100%), and no function violates the budget. - PR diff against
docs/help-examples-execute: 876 changed lines, under the 1,000-line limit.
Not suggested (outside this diff): on_a_terminal repeats most of interrupt_the_hidden_key_prompt (tests/cli_integration.rs:1734): the terminal setup, the unsafe pre_exec block, the output reader, and the kill-on-timeout cleanup. GitHub can't suggest changes to lines this PR doesn't touch. A follow-up could move that helper onto the same spawn and cleanup code so there is one unsafe block.
7e7814c to
2a34199
Compare
On a terminal, a command that lacks the organization, environment, or wallet it needs now asks for it instead of failing. A picker, filtered by typing part of a name or ID, lists each choice as "name UUID" from the same sources as organizations list, environments list, and wallets list, in the environment when one is selected. Afterwards a notice names the flags that select the same scope. API commands ask for the scope their path needs. Friendly payment creation asks for a wallet, and friendly wallet creation for an environment. environments list asks for an organization, and profiles create for an organization and environment. A positional target is still typed. Nothing is asked when stdin or stderr is not a terminal, with --no-input, with JSON or NDJSON output, or with --dry-run, so scripts see the same errors as before. Esc leaves the scope unchanged and the command reports what is missing; Ctrl-C exits with code 130. An API key cannot list organizations or environments, so with a key only a wallet is offered and a missing organization fails as before. Picking never sends a change, which still needs --execute. API names are scrubbed before the picker draws them. The picker resolves the credential once and exchanges at most one organization token. inquire draws it through crossterm, which it now runs with its event features. Pseudo-terminal tests cover a pick, Esc, Ctrl-C, the no-prompt flags, an empty wallet list, an API key without an organization or environment, and a login that picks an organization and then an environment.
2a34199 to
9f29f81
Compare
Stack: master ← #20 ← #22 ← #57 ← #24 ← #19 ← #26 ← #27 ← #28 ← #29 ← #30 ← #55. Rebased onto master (#53, #56) on 2026-10-19.
Summary
On a terminal, a command that lacks the organization, environment, or wallet it needs now asks for it instead of failing. Implements DEV-2903 (first part).
payments send/receivewallets createenvironments listprofiles createorganizations list,environments list, andwallets list(in the selected environment). Each shows asname UUID. Typing filters by any part of the name or ID.--output table, or with--no-input,--json,--output json|ndjson, or--dry-run. Those runs fail with the same error as before.--org is required(exit 2).Changes after review
api::walletsbuilds its path and query from the registry operationGetAllOrganizationsWalletsAsUser, through a newRequest::scoped. More than one--envnow fails with the same error aswallets list. Before, the error was discarded and the picker listed every environment's wallets.pick::needsmatches everyLocalCommandandProfileCommandvariant, so a new local command must decide whether it needs a scope.Review exceptions
inquire =0.9.4, default features off pluscrossterm. It draws the picker through crossterm, which feat(cli): fit human tables to the terminal and scrub all API text #15 already added, so the CLI keeps one terminal backend. It enables crossterm'seventsfeature, which bringsmio,signal-hook,signal-hook-mio, andderive_more. New crates from inquire itself:inquireanddyn-clone. Thefuzzyfeature is left off: its default substring filter matches names and IDs, and droppingfuzzyavoidsfuzzy-matcherandthread_local.terminal::ChoiceandTerminal::pick(prompts belong toterminal),api::wallets(HTTP belongs toapi),input::Request::scoped, andauth::exchangeandauth::list(split out ofresolve_organizationanddiscoverso the picker resolves once). Nothing is added to the library's public API.Choice::name(). AChoicescrubs its API-supplied name inChoice::new, and private fields keep unscrubbed text from reaching the picker.PickerScreenturns bracketed paste off and shows the cursor on drop. A signal that ends the command while the picker is open skips inquire's own cleanup.TerminalModesrestores the terminal attributes, as for the hidden key prompt.Deferred
wallets getwith no ID. This changes clap's required argument.auth import-key(organization and one environment) and webhook path scopes do not ask yet.payments send --unit satswithout--amountasks first, then fails.Tests
--json,--no-input, and--dry-runneither ask nor list; an API key without an organization keeps--org is required; a login picks an organization and then an environment; an empty wallet list says so.Checks
On
9f29f81:cargo fmt --check,cargo clippy --locked --all-targets -- -D warnings,cargo machete --with-metadata: pass.cargo test --locked: 93 unit and 65 integration tests pass.VOLTAGE_BLESS=1 cargo test --lockedleaves the tree clean.python3 scripts/check-coverage.py: pass.scripts/crap-report.sh): no function at or above 20. Highest isapi::wait_for_paymentat 19.66, unchanged from or lower than master (19.66).voltage-pr-reviewand thevoltage-backend-engineeringRust checklist, against the stack base. Findings are fixed in this commit.Not run: the staging and live tutorials, which need credentials.