Skip to content

Refactor: extract shared muted-footnote/stack render helpers#40

Merged
alexkroman merged 3 commits into
mainfrom
claude/refactoring-wind-mWqmR
Jun 8, 2026
Merged

Refactor: extract shared muted-footnote/stack render helpers#40
alexkroman merged 3 commits into
mainfrom
claude/refactoring-wind-mWqmR

Conversation

@alexkroman

Copy link
Copy Markdown
Collaborator

The usage and audit commands each re-derived the same Rich idiom:
build a primary view, optionally tack on a dim "Hidden: N … Use --flag to
show them." note, and wrap the result in a Group (or return it bare when
there's nothing to stack). This duplicated the Group/None branching and the
Text(..., style="aai.muted") construction across both files.

Add two small helpers to output.py:

  • muted(text) — a dim secondary line (empty-state messages, footnotes).
  • stack(*items) — combine renderables top-to-bottom, dropping None; a lone
    survivor is returned bare so a single table isn't wrapped in a redundant
    Group.

Rewrite both command renderers in terms of them. Output is byte-identical
(snapshot and command tests unchanged); this only removes the repeated
composition logic.

claude added 3 commits June 8, 2026 02:04
The `usage` and `audit` commands each re-derived the same Rich idiom:
build a primary view, optionally tack on a dim "Hidden: N … Use --flag to
show them." note, and wrap the result in a `Group` (or return it bare when
there's nothing to stack). This duplicated the Group/None branching and the
`Text(..., style="aai.muted")` construction across both files.

Add two small helpers to `output.py`:

- `muted(text)` — a dim secondary line (empty-state messages, footnotes).
- `stack(*items)` — combine renderables top-to-bottom, dropping None; a lone
  survivor is returned bare so a single table isn't wrapped in a redundant
  Group.

Rewrite both command renderers in terms of them. Output is byte-identical
(snapshot and command tests unchanged); this only removes the repeated
composition logic.
The `usage` and `audit` commands each wrapped `timeparse.parse_iso_utc` in
their own private parse/format helpers — `_parse_usage_timestamp` +
`_format_usage_day` (calendar day) in account.py, and `_parse_time` +
`_format_time` (YYYY-MM-DD HH:MM:SS) in audit.py — to turn an ISO string
into a display value with a stringify-fallback for unparseable input.

Lift the two display formatters next to the parser they build on:

- `timeparse.format_utc_day(value)` -> "YYYY-MM-DD"
- `timeparse.format_utc_datetime(value)` -> "YYYY-MM-DD HH:MM:SS"

Both fall back to the stringified input (or "") when the value isn't a
parseable timestamp. The commands now call these directly; their local
parse/format helpers are gone. (audit's `_parse_time` stripped tzinfo only
to feed strftime, which ignores it — so formatting the UTC datetime directly
is byte-identical.) Output is unchanged; tests for the formatters move to
test_timeparse.py.
`keys create` (without --project) resolved the account's first project id
through three sequential guards — empty project list, unparseable first
entry, missing/invalid id — each raising the identical "no project to
create a key in" APIError inline in the command body.

Extract `_default_project_id(account_id, jwt)` to fold all three into one
helper that raises the single canonical error once. The command body drops
to a one-line `pid = project_id if ... else _default_project_id(...)`.
Behavior and error message are unchanged; existing tests cover all three
failure branches plus both success paths.
@alexkroman alexkroman merged commit a77b1f1 into main Jun 8, 2026
10 checks passed
@alexkroman alexkroman deleted the claude/refactoring-wind-mWqmR branch June 8, 2026 03:01
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