Skip to content

feat(cli): draw context and auth status as cards on a terminal - #107

Merged
thebrandonlucas merged 1 commit into
feat/cli-look-07-wordmarkfrom
feat/cli-look-08-context
Oct 23, 2026
Merged

thebrandonlucas merged 1 commit into
feat/cli-look-07-wordmarkfrom
feat/cli-look-08-context

Conversation

@thebrandonlucas

@thebrandonlucas thebrandonlucas commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Stack position: 8 of 13 in the look-and-feel stack. Base: feat/cli-look-07-wordmark (#106).

Problem

voltage context and voltage auth status answer "who am I and where am I pointed?", the question a person checks most often. Their output was the same plain field list as any API result, with nothing to frame it.

Behavior

On a terminal (stdout is a TTY, table output):

╭─ voltage auth status ─────────────╮
│ account     me                    │
│ email       you@example.com │
│ expired     false                 │
│ expires_at  1792709018            │
│ kind        user                  │
╰───────────────────────────────────╯
  • The title is in Voltage orange (feat(cli): color help headers Voltage orange and honor FORCE_COLOR #105), field names are bold, and in context the (flag) / (environment) sources are dim. The borders are dim.
  • Without a UTF-8 locale, the borders are +, -, and |.
  • The content is exactly the field lines from before, with nothing dropped or shortened. A card wider than the terminal falls back to those plain lines rather than truncating an ID or path. context with long config paths is about 104 columns wide, so it shows as a card only on wide terminals.
  • Redirected output (--output table | cat) and JSON are unchanged.

Design notes

  • Envelope::titled(title) (serde-skipped card field) marks a result for a card. Only context and auth status set it.
  • human::View gains cards (stdout is a TTY), glyphs, and depth. card() measures each line's display width with styles stripped, so styled lines and borders line up. Borders and the title are painted after layout.
  • Dim sources apply wherever settings render with color on.

Try it on staging

Setup: Try a pull request on staging (added by #97).

voltage auth status --account me
voltage context --account me

Expect: both drawn in a rounded box titled voltage auth status / voltage context in orange. Make the terminal at least ~105 columns wide for context; narrower, it shows the plain lines.

LANG=C LC_ALL=C voltage auth status --account me
COLUMNS=30 voltage auth status --account me
voltage auth status --account me --output table | cat
voltage auth status --account me --json

Expect: an ASCII +- voltage auth status -+ box; then plain lines (too narrow); then plain lines (redirected); then JSON, unchanged.

Validation

  • cargo fmt --check, cargo clippy --locked --all-targets -- -D warnings, cargo machete --with-metadata, cargo test --locked (161 unit and 127 integration tests), and python3 scripts/check-coverage.py all pass.
  • Unit tests check the exact Unicode and ASCII cards (the title sets the width when it is widest), that a styled card strips to the plain one, the fallback to plain lines one column too narrow and off a terminal, and dim settings sources.
  • New integration test: a redirected context --output table --color always has plain field lines and no card.
  • Checked by hand on staging with both commands, in Unicode and ASCII.
  • CRAP: 0 of 725 measured functions at or above 20. The highest is 18.00 (src/cli.rs endpoint, untouched).

Docs

docs/reference/output.md and CHANGELOG.md.

@thebrandonlucas
thebrandonlucas added this pull request to stack #92 October 22, 2026 22:39
@thebrandonlucas
thebrandonlucas marked this pull request as ready for review October 22, 2026 22:41

@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.

Review of 799b6db (base #106 01ff3ef). This is not an approval yet, because nothing has validated this head: CI has not run on it, and I have not run the gate or the CRAP report. The code review found no bugs:

  • card is #[serde(skip)], so JSON, NDJSON and --output-file output are unchanged, and cards also require stdout to be a terminal.
  • Width is measured on the text without styles, every row is inner + 4 wide, and inner - title.len() - 1 cannot underflow.
  • A card that does not fit falls back to the plain lines, and Glyphs::ASCII draws ASCII frames.
  • The cards show no new data: they read no secret and make no network request.

One nonblocking note: the description includes a real @voltage.cloud email address. Please replace it with a placeholder such as you@example.com, as #106 does.

I will approve once CI or my local gate passes on this head.

@thebrandonlucas
thebrandonlucas force-pushed the feat/cli-look-08-context branch from 799b6db to 62ef90c Compare October 23, 2026 03:30
@thebrandonlucas

Copy link
Copy Markdown
Contributor Author

Replaced the real email in this description, and in #112's, with you@example.com. This PR's head changed only through the rebase onto master; every layer passed the gate (see #86).

On a terminal, voltage context and voltage auth status draw their field
lines inside a box titled in Voltage orange, with rounded corners (or +-|
without a UTF-8 locale), bold field names, and dimmed sources. Widths are
measured without styles. A card wider than the terminal, and any redirected
output, keeps the plain field lines.
@thebrandonlucas
thebrandonlucas force-pushed the feat/cli-look-08-context branch from 62ef90c to d5bd5fa Compare October 23, 2026 12:38

@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 d5bd5fa, a rebase onto #106 4e764c3. The patch matches 799b6db, where my review found no bugs. card is #[serde(skip)], cards need stdout on a terminal, the width math cannot underflow, a card that does not fit falls back to plain lines, and nothing new is read or requested. Validation on this head, in nix develop: cargo fmt --check, cargo clippy --locked --all-targets -- -D warnings, cargo machete --with-metadata, cargo test --locked (175 unit, 134 integration) and python3 scripts/check-coverage.py passed. CRAP: 758 measured functions, none at or above 20, highest wait_for_payment at 17.05. CI is green. My earlier note still applies: please replace the real @voltage.cloud email address in the description with a placeholder.

@tee8z

tee8z commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Correction to my approval: the description no longer contains the email address, so there is nothing to change there. Thanks.

@thebrandonlucas
thebrandonlucas merged commit 85b9eaf into master Oct 23, 2026
9 of 14 checks passed
@thebrandonlucas
thebrandonlucas deleted the feat/cli-look-08-context branch October 23, 2026 15:47
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.

2 participants