Skip to content

feat(auth): default human views and default fields for auth status/login - #129

Open
jpage-godaddy wants to merge 6 commits into
mainfrom
human-status-view
Open

jpage-godaddy wants to merge 6 commits into
mainfrom
human-status-view

Conversation

@jpage-godaddy

@jpage-godaddy jpage-godaddy commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

Refs DEVEX-1267.

Problem

The built-in auth status / auth login declared no human view, so their columns rendered in alphabetical order (ENV EXPIRED EXPIRES_AT IDENTITY PROVIDER REFRESHABLE), and a consumer had no supported way to change them short of replacing the whole auth group.

Changes

  • Default views. Both commands render through the view ids auth:status / auth:login (AUTH_STATUS_VIEW_ID, AUTH_LOGIN_VIEW_ID). The engine registers default_auth_status_view() / default_auth_login_view() (identity, expires, env, provider, expired, refreshable, scopes) only when nothing already holds the id, so a view from CliConfig::with_view or register_global_human_view always wins, including across a later register_auth_provider.
  • Default fields. CliConfig::with_auth_status_default_fields / with_auth_login_default_fields set the commands' default_fields, so a consumer can leave a column out by default (e.g. provider) while it stays available with --fields. As with any default_fields, this also projects JSON/TOON output.
  • Schema. AuthStatusEntry / AuthLoginResult derive JsonSchema and are registered on the commands, so --help lists every output field (marking defaults) and --schema works.
  • --expr and views. A fixed view rendered a blank table when --expr reshaped the result into fields it doesn't name (a regression for auth status / auth login, which previously rendered generically), and view-based --fields validation rejected names from the expression's result. In human output, --expr now means the command has no view: the result renders generically and --fields is validated and projected against it, as for JSON. --filter keeps the view. This applies to every view-backed command. (refined during review)
  • Help fixes found along the way.
    • --fields printed clap's [default: ...] after the last row of the output-field table; it is now on the flag's first line.
    • --interactive always claimed "(default when TTY is detected)"; it now says so only when auto_interactive is enabled.

Testing

New tests/auth_views.rs covers the default views, a view override (and that it survives a later provider registration), default fields keeping provider selectable, JSON projection, the help output, and --expr / --fields interplay (generic rendering, validation, and projecting from the expression result). tests/interactivity.rs covers the --interactive help text. cargo fmt, clippy -D warnings, cargo doc, cargo test --all-targets, cargo test --doc, check-module-size.sh and missing-docs (0) all pass. Also checked end to end against gddy with a local path patch.

🤖 Generated with Claude Code

The built-in `auth status` and `auth login` had no human view, so their
columns rendered in alphabetical order and a consumer could not change
them without replacing the whole auth group.

- Render both through the views `auth:status` / `auth:login`
  (`AUTH_STATUS_VIEW_ID`, `AUTH_LOGIN_VIEW_ID`). The engine registers
  `default_auth_status_view()` / `default_auth_login_view()` (identity,
  expires, env, provider, ...) unless the consumer already registered a
  view under that id, so an override is never clobbered.
- Add `CliConfig::with_auth_status_default_fields` and
  `with_auth_login_default_fields` to choose the default `--fields`
  without removing columns from the view.
- Register a JSON schema for `AuthStatusEntry` / `AuthLoginResult` so
  `--help` lists every output field and `--schema` works.
- Print `[default: ...]` for `--fields` on the flag's first help line
  instead of after the last row of the output-field table.
- Only say `--interactive` is the default on a TTY when
  `auto_interactive` is enabled.

Refs DEVEX-1267
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The fixed auth views hide valid reshaped expression results in human output.

1 open issue
What changed in this PR

Adds customizable human views and default fields for built-in authentication commands.

Changes:

  • Registers overridable auth views and output schemas.
  • Adds configuration for default auth fields.
  • Corrects help text and adds regression coverage.
File Description
cli-engine/​tests/​interactivity.rs Tests conditional interactive help.
cli-engine/​tests/​auth_views.rs Tests auth views, overrides, fields, and help.
cli-engine/​src/​lib.rs Exports auth view APIs.
cli-engine/​src/​flags/​register.rs Corrects default interactive help.
cli-engine/​src/​cli/​schema_tree.rs Repositions field defaults in help.
cli-engine/​src/​cli/​registration.rs Registers auth views and applies default fields.
cli-engine/​src/​cli/​mod.rs Adjusts help for automatic interactivity.
cli-engine/​src/​cli/​config.rs Adds auth default-field settings.
cli-engine/​src/​auth/​mod.rs Re-exports auth view APIs.
cli-engine/​src/​auth/​commands.rs Defines views and attaches schemas.
cli-engine/​docs/​auth.md Documents auth output customization.

Review effort: Balanced

Comment thread cli-engine/src/cli/registration.rs
…of the data

A fixed human view rendered an all-blank table when `--expr` reshaped the
result into fields the view never names (e.g. `auth status --expr
'{user: identity}'`). Render such data generically instead. Only data that
is objects, none of which resolve any of the view's columns, falls back;
a view that matches at least one column keeps rendering as before.

Refs DEVEX-1267
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Field validation and rendering fallback introduce unresolved regressions in human output selection.

1 open issue
1 previously missed issue

In code that hasn't changed since last review

Medium severity Validate fields after expression reshaping

cli-engine/​src/​auth/​commands.rs:172

Adding this view rejects explicit fields created by --expr before the new rendering fallback can run. For example, auth status --provider primary --env prod --expr '{user: identity}' --fields user --output human fails with an unknown-field error because middleware/run.rs:516–539 validates user against the auth view before evaluating the expression. Login is affected too. Defer view-specific validation until the transformed shape is known, and validate explicit selections against the transformed data when using generic rendering. Add regression tests for both commands.

1 resolved since last review

Review effort: Balanced

Comment thread cli-engine/src/output/human/mod.rs Outdated
jpage-godaddy and others added 2 commits October 20, 2026 12:14
A view whose columns are all optional would fall back to generic rendering
for an ordinary response that merely lacked those fields, dropping the view.
Fall back only when `--expr` reshaped the data.

Refs DEVEX-1267
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
`--expr` can reshape the result into any shape, so the view's columns say
nothing about what `--fields` may name. Skip the view-catalog check in that
case, and let the generic fallback apply an explicit `--fields` to the
reshaped data.

Refs DEVEX-1267
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@jpage-godaddy

Copy link
Copy Markdown
Collaborator Author

Re the review-body finding "Validate fields after expression reshaping": fixed in 5117d05. --fields is no longer validated against the view's columns when --expr is set, since the expression's result can be any shape. When the generic fallback renders a reshaped result, an explicit --fields is applied to it, so auth status --expr '{user: identity}' --fields user now works for both auth status and auth login. This also fixes the same failure for any other view-backed command. Without --expr, an unknown --fields name is still rejected (covered by tests).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Post-expression human output can discard valid explicit fields and silently accept invalid selections.

2 open issues
1 resolved since last review

Review effort: Balanced

Comment thread cli-engine/src/middleware/run.rs Outdated
Comment thread cli-engine/src/output/human/mod.rs
`--expr` hands the caller control of the result's shape, so a registered
view's columns no longer describe it. Treat the command as having no view
in human output when `--expr` is set; the existing pipeline then validates
and projects `--fields` against the expression's result, as it does for
JSON. This replaces the earlier fallback heuristic and skipped validation,
both of which left edge cases (typos accepted, explicit fields dropped when
the result kept one view column). `--filter` still keeps the view.

Refs DEVEX-1267
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

No unresolved blocking issues remain, and focused regression tests cover the changed behavior, though tests were not executed during this review.

No open issues 🎉

2 resolved since last review

Review effort: Balanced

@kenperkins

Copy link
Copy Markdown

Possible bug: --expr combined with with_auth_*_default_fields may give empty output

Re the new view_id override in cli-engine/src/middleware/run.rs: I think the default-fields fallback still runs after --expr changes the result's shape. If --fields isn't passed, effective_fields falls back to default_fields, and apply_pipeline projects onto those names after the expression runs. Default fields are never checked against the data (fields_are_default: true), so names the expression's result doesn't have are dropped without any error.

Untested repro, from reading the code:

let cli = cli_with(config().with_auth_status_default_fields(NO_PROVIDER));
run(&cli, &["auth", "status", "--provider", "primary", "--env", "prod",
            "--expr", "{user: identity}", "--output", "human"]).await

I'd expect user tester. As far as I can tell, {user: "tester"} gets projected onto identity,expires_at,env,…, which leaves {}, so the output is blank. JSON output would have the same problem.

The existing expr_* tests don't set default fields, so they wouldn't catch this. Since hiding provider with with_auth_status_default_fields is the main reason to use the new API, this combination seems likely to come up in practice.

One possible fix: when --expr is set and --fields wasn't passed explicitly, skip the default-fields projection, because default fields describe the command's own output, not the expression's. Roughly:

let effective_fields = if self.fields_explicit {
    self.fields.as_str()
} else if !self.expr.is_empty() {
    ""
} else {
    default_fields
};

This would also change JSON/TOON output for any command that has default_fields and is run with --expr. I think that's the right behavior, but it's worth deciding on purpose. Am I missing something that already handles this?

When `--expr` was set without an explicit `--fields`, `effective_fields`
still fell back to the command's `default_fields` and projected those names
onto the expression's result. Since default-field projection is never
validated against the data, names the result lacked were silently dropped,
collapsing e.g. `auth status --expr '{user: identity}'` to `{}` / `(no data)`
whenever the command had default fields set (as a consumer does to hide
`provider`). Fall back to no projection under `--expr` instead. Affects
JSON/TOON too, intentionally: default fields describe the command's own
output, not the expression's.

Refs DEVEX-1267
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jpage-godaddy

Copy link
Copy Markdown
Collaborator Author

Good catch, and you're right — confirmed the repro. With default_fields set, auth status --expr '{user: identity}' (no --fields) projected identity,expires_at,env,… onto {user: tester} and collapsed it to {} / (no data), in JSON too. My round-3 change dropped the view under --expr but left effective_fields falling back to default_fields, so the projection still ran.

Fixed in b4f3d7a with your suggested change: under --expr with no explicit --fields, effective_fields is "" rather than default_fields, so nothing is projected and the expression's result renders as-is. An explicit --fields still applies; --filter still keeps the view and default fields. As you noted this also changes JSON/TOON for any default_fields command run with --expr, which is the intended behavior. Added a regression test with default fields set (the gap the existing expr_* tests missed), covering status and login in both human and JSON, and verified against the gddy build.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

No unresolved blocking issues remain, and focused regression tests cover the changed behavior and previously reported problems.

No open issues 🎉

Review effort: Balanced

This branch has not been deployed

No deployments
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.

3 participants