Skip to content

feat(cli): name the next step after an accepted receive or quote - #62

Merged
thebrandonlucas merged 3 commits into
masterfrom
feat/cli-next-step-after-accept
Oct 21, 2026
Merged

thebrandonlucas merged 3 commits into
masterfrom
feat/cli-next-step-after-accept

Conversation

@thebrandonlucas

@thebrandonlucas thebrandonlucas commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Stack 2 of 6. Base: fix/cli-usd-quote-guidance (#61). Next: feat/cli-picker-currency.

Closes #52, closes #36.

Problem

Behavior

Case Before After
payments receive, accepted, human output accepted <id> adds hint: Show the invoice or address with \voltage payments get ID --org ORG --env ENV`, or pass --wait ready next time (--qr or --copy for a BOLT11 invoice).`
quotes create, accepted, human output accepted <id> adds hint: Show the quote with \voltage quotes get ID --org ORG --env ENV` once it is ready.`
Accepted payments send, --quiet, --output json, or a --data body without an id — no hint
quotes get --id ID (any command with a positional resource ID) usage error same as quotes get ID
Both the positional ID and --id — usage error, cannot be used with

The hint's command carries the effective scope as flags: --org, each --env, and --account NAME when an account is selected, quoted for the shell. These flags win over a profile and over VOLTAGE_* variables, so the pasted command reaches the same organization, environment, and credential however the original command chose them.

The ID and --id form a required group, so the usage line shows <QUOTE_ID|--id <ID>> and a test pins it. docs/commands.md (with scripts/check-coverage.py) and login-and-profiles.md mention --id ID. The CLI still does not wait by default (option 2 in #52).

Checks

On head 908b529 (this PR's commit is cc73897; the squashed #64 and #65 commits sit on top, unchanged):

  • The gate passes in nix develop: cargo fmt --check, cargo clippy --locked --all-targets -- -D warnings, cargo machete --with-metadata, cargo test --locked (110 unit, 93 integration), and python3 scripts/check-coverage.py.
  • New paths have tests:
    • The receive and quote hints, with their --org/--env.
    • scope_flags_name_the_effective_scope: a quoted account, and an empty scope.
    • No hint for --quiet, JSON output, an accepted send, or a quotes create --data body without an id, which is the let id = id?; early return.
    • --id on quotes get, both IDs at once, neither ID, and the -h usage line.
  • CRAP: 0 of 525 measured functions are at or above 20. The highest is wait_for_payment at 19.60, unchanged from master. next_step is 3.00 and scope_flags is 1.00.
  • I reviewed the diff with voltage-pr-review and the Rust style checklist.
  • The commit is signed G blu@blu.cx, with no trailers.
  • Not run: a staging receive.

@thebrandonlucas
thebrandonlucas added this pull request to stack #63 October 20, 2026 18:02
@thebrandonlucas
thebrandonlucas force-pushed the feat/cli-next-step-after-accept branch from 0df238a to d4a558b Compare October 20, 2026 18:10
@thebrandonlucas
thebrandonlucas marked this pull request as ready for review October 20, 2026 18:10

@thebrandonlucas thebrandonlucas left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cicero review of d4a558b (base: #61 a149b80)

No blocking findings. Checked:

  • next_step (src/api.rs:888) runs only on a 202 in human output. --quiet is honored through Terminal::notice. The integration test covers table, --quiet, JSON, the quote case and the no-hint send. The hint: prefix matches output.rs:323.
  • TargetFlags (src/cli.rs:316): required_unless_present plus conflicts_with give exactly one ID. command().debug_assert() (src/cli.rs:1280) passes, so the hidden --id does not clash with any command's own --id. The flag, positional, both, and neither cases are tested.

Nit: the CHANGELOG advertises a hidden flag

CHANGELOG.md:17 says every command with a resource ID "also takes it as --id ID". The flag is hide = true (src/cli.rs:323), so --help never shows it. Either is fine: keep it hidden and drop or soften the CHANGELOG line ("--id ID is accepted where a positional ID is expected"), or unhide it. Your choice; not blocking.

Note, no change needed

A receive whose outcome is recovered through reconcile_payment gets no hint, because the recovered response is a 200 read, not a 202. That read already returns the payment, so this is fine.

Checks on d4a558b

  • Gate in nix develop: fmt, clippy, machete, tests (108 unit, 93 integration) and coverage pass. The tree is clean afterwards.
  • CRAP: 0 of 520 measured functions at or above 20. The highest is wait_for_payment at 19.60; next_step and TargetFlags::id are below that.
  • Not run: CodeRabbit status.

@thebrandonlucas
thebrandonlucas force-pushed the feat/cli-next-step-after-accept branch from d4a558b to 72954c8 Compare October 20, 2026 18:17

@thebrandonlucas thebrandonlucas left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at 72954c8 (Aurelius). The next-step hint is correct: it shows only for a 202 in human output, respects --quiet through Terminal::notice, and is skipped on the wait path and for a send. The tests cover each case.

Low: src/cli.rs:317: making resource_id an Option with required_unless_present changes every get usage line from <QUOTE_ID> to [QUOTE_ID]. voltage quotes get -h now shows Usage: voltage quotes get [OPTIONS] [QUOTE_ID], as if the ID were optional, and --id is hidden. The new CHANGELOG line ("Help still shows only the argument") doesn't cover this. Fix: I tried #[group(required = true, multiple = false)] on TargetFlags, without required_unless_present or conflicts_with. The usage becomes <QUOTE_ID|--id <ID>>, and "both" still fails with exit 2. That shows --id, so unhide it at the same time, or keep it hidden and accept the [QUOTE_ID] usage. Either way, add a help assertion so the usage line is pinned.

Checks:

  • Gate on d4a558b: fmt, clippy, machete, tests (108 unit, 93 integration) and coverage pass.
  • CRAP on d4a558b: 0 functions at or above 20. The highest is wait_for_payment at 19.60.
  • 72954c8 changes only CHANGELOG.md and troubleshooting.md from d4a558b. Signed G blu@blu.cx.

@thebrandonlucas
thebrandonlucas force-pushed the feat/cli-next-step-after-accept branch from 72954c8 to cf3f0cc Compare October 20, 2026 18:24

@thebrandonlucas thebrandonlucas left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review at cf3f0cc (Aurelius). My low finding is fixed. TargetFlags is a required group, --id is visible, and a test pins Usage: voltage quotes get [OPTIONS] <QUOTE_ID|--id <ID>> and the error when neither ID is given. The CHANGELOG matches. No findings remain.

Checks on cf3f0cc: fmt, clippy, machete, tests (108 unit, 93 integration) and coverage pass, and the tree is clean. Signed G blu@blu.cx.

@thebrandonlucas thebrandonlucas left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review at cf3f0cc. This is not an approval. I found no new problems.

  • TargetFlags is #[group(required = true, multiple = false)], and --id is visible. The test pins Usage: voltage quotes get [OPTIONS] <QUOTE_ID|--id <ID>> and the error when neither ID is passed. Passing both still exits 2.
  • The CHANGELOG line matches the new behavior. docs/commands.md is still current: check-coverage.py passes.

Checks on cf3f0cc:

  • Gate in nix develop: fmt, clippy, machete, tests (108 unit, 93 integration) and coverage pass, and the tree is clean afterwards.
  • CRAP, run with the rustup toolchain: 0 of 520 measured functions are at or above 20. The highest is wait_for_payment at 19.60.

@tee8z tee8z left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at cf3f0cc. CRAP on this head: 0 of 520 functions at or above 20, highest wait_for_payment at 19.60. One thing I'd fix before merge (inline on next_step), plus nits:

  • docs/commands.md ("IDs are positional; enclosing scope uses flags", pinned in scripts/check-coverage.py) and docs/guides/login-and-profiles.md ("Resource IDs are positional") still describe IDs as positional only. Please mention --id ID.
  • next_step's let id = id?; early return has no test. It is reachable, for example with quotes create --data and a body without id. AGENTS.md asks for a test of each new early return.
  • The description reports the checks on d4a558b. That commit is gone after the force-push and differed from the head (--id hidden, group not required). Please report them on the head.
  • The PR description ends with a "Generated with Claude Code" line; AGENTS.md says to leave tool attribution out of PR descriptions.

Comment thread src/api.rs Resolved

@tee8z tee8z left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes on cf3f0cc. The existing scope finding remains unresolved: next_step emits a bare payments get or quotes get command. With scope supplied through flags or a profile, copying that command loses the organization/environment and credential selection. Carry the effective scope into the command, or explicitly require the same scope options.

Add a behavior test for the new missing-resource-ID early return. Update the generated command reference and login guide to describe --id ID.

Validation: cargo fmt --check, cargo clippy --locked --all-targets -- -D warnings, cargo machete --with-metadata, cargo test --locked, and python3 scripts/check-coverage.py passed. CRAP: 520 measured functions, zero violations, highest wait_for_payment 19.60; 139 test functions unmeasured.

@thebrandonlucas

Copy link
Copy Markdown
Contributor Author

@tee8z Both reviews are addressed in cc73897. The PR head is 908b529, with the squashed #64 and #65 commits on top.

  • Scope in next_step: see the inline reply.
  • Missing-ID early return: the accepted-hint integration test now runs quotes create --data with a body that has no id, and checks that no hint is printed.
  • --id ID docs: docs/commands.md (and the line scripts/check-coverage.py pins) and login-and-profiles.md now mention it.
  • Description: it reports the checks on 908b529, and the stale reviewer-validation section is gone. It has no "Generated with" line.

@tee8z tee8z left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved 908b529 against fix/cli-usd-quote-guidance (#61 641003e). My change request on cf3f0cc is resolved in cc73897:

  • Scope: next_step now names the effective scope as flags through scope_flags, for example voltage payments get ID --org ORG --env ENV --account NAME. Scope.account is filled from --account or from the profile, so a profile-selected login carries over. A picker-filled --org or --env carries over too. With --account given, VOLTAGE_API_KEY is ignored, just as with --profile. Without an account, the copied command picks the same VOLTAGE_API_KEY or sole saved credential. The account name is quoted for the shell.
  • Early return: the integration test now runs quotes create --data with a body that has no id, and checks that no hint is printed.
  • Docs: docs/commands.md, the line in scripts/check-coverage.py that pins it, and login-and-profiles.md now describe --id ID.

Nonblocking: the hint does not carry --api-url, --auth-url or --config-dir when the command used them.

Validation on this head, in nix develop: cargo fmt --check, cargo clippy --locked --all-targets -- -D warnings, cargo machete --with-metadata, cargo test --locked (110 unit, 93 integration) and python3 scripts/check-coverage.py passed. CRAP: 525 measured functions, none at or above 20, highest wait_for_payment at 19.60; 139 functions were unmeasured. CI is green.

Base automatically changed from fix/cli-usd-quote-guidance to master October 21, 2026 15:58
thebrandonlucas and others added 3 commits October 21, 2026 10:58
An accepted payments receive or quotes create returns no body, so
human output now names the command that shows the invoice, address,
or quote, with the --org, --env, and --account that the command used.
--quiet and machine-readable output leave the hint out, and so does a
request body without an ID.

A command that takes a resource ID also takes it as --id, as
quotes create and payments send do, and rejects both at once.

Closes #52
Closes #36
The wallet picker listed only a name and an ID, so a USD wallet looked
like a BTC wallet. Each wallet now shows its currency between the two
when all of its balances report the same one, and typing the currency
filters on it. A wallet with no balance currency, or with balances
that disagree, shows only its name and ID.

Closes #50
* feat(cli): show each wallet's currency in the picker

The wallet picker listed only a name and an ID, so a USD wallet looked
like a BTC wallet. Each wallet now shows its currency between the two
when all of its balances report the same one, and typing the currency
filters on it. A wallet with no balance currency, or with balances
that disagree, shows only its name and ID.

Closes #50

* fix(scripts): build, then run the command after a leading --build

`scripts/voltage-staging --build login ...` passed `--build` to the
binary, which rejected it. A leading `--build` in either wrapper now
builds and then runs the remaining arguments, if any. The wrapper still
refuses `--config-dir`, `--api-url` and `--auth-url` before it builds,
and a failed build exits with cargo's status without running the command.

Closes #37.
@thebrandonlucas
thebrandonlucas force-pushed the feat/cli-next-step-after-accept branch from 908b529 to 0b6e476 Compare October 21, 2026 15:58
@thebrandonlucas
thebrandonlucas merged commit 0e034d2 into master Oct 21, 2026
7 checks passed
@thebrandonlucas
thebrandonlucas deleted the feat/cli-next-step-after-accept branch October 21, 2026 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

payments receive: show the invoice (or how to get it) after --execute quotes create --id but quotes get QUOTE_ID

2 participants