Skip to content

feat(ui): restyle status prefixes per output mode; warnings as CI annotations - #287

Merged
oleg-flamingocx merged 12 commits into
mainfrom
feat/status-prefix-restyle
Aug 5, 2026
Merged

feat(ui): restyle status prefixes per output mode; warnings as CI annotations#287
oleg-flamingocx merged 12 commits into
mainfrom
feat/status-prefix-restyle

Conversation

@oleg-flamingocx

@oleg-flamingocx oleg-flamingocx commented Aug 5, 2026

Copy link
Copy Markdown
Contributor
One central hook (ApplyStatusPrefixTheme, wired into ApplyGlobalOutputFlags)
re-themes the package-level pterm printers every call site prints through:

- Interactive terminals drop the block badges for quiet glyph prefixes from
  the shared GlyphSet (dim bullet for info, triangle/cross/check for
  warning/error/success), inheriting its ASCII fallback.
- Non-interactive output (CI, pipes, --plain) keeps word tags for
  grep-ability but lowercase, column-aligned and foreground-colored:
  info/warning/error/success/debug, no background blocks.
- Inside GitHub Actions, warnings are teed into ::warning:: annotations so
  they surface on the PR; errors already got richer annotations from the
  shared error handler, which now also stops prepending a manual failure
  glyph the themed prefix carries.

--silent still wins (theme runs after the flag handlers), NO_COLOR degrades
to plain glyph/tag text via the existing color contract.

Summary by CodeRabbit

  • New Features
    • Added clearer status formatting for interactive and non-interactive output.
    • Added GitHub Actions warning annotations with sanitized, deduplicated messages.
    • Verbose output now includes consistent timestamps.
  • Bug Fixes
    • Removed unwanted indentation from progress and status messages.
    • Improved error display consistency with the standard themed error prefix.
  • Style
    • Simplified list output by avoiding repeated status labels.
    • Status messages now use aligned severity labels or interactive symbols based on the output environment.

readline v1.5.x changed prompt teardown (stdin wrapping, ioloop/Close
semantics) in ways promptui v0.9.0 was never adapted to: every interactive
picker leaked readers parked on stdin/channel sends, which could wedge the
process after the prompt returned - terminal stopped echoing, Ctrl+C was
swallowed, the command never exited (seen on 'openframe cluster status'
with interactive selection).

Pin readline to the commit promptui declares and exclude the broken
v1.5.0/v1.5.1 so 'go get -u' cannot silently re-upgrade onto them.
promptui is unmaintained (last release Oct 2021, master == v0.9.0) and its
readline dependency is the root of the interactive-prompt teardown bugs the
previous commit pinned around. Replace it with charmbracelet/huh, which is
actively maintained and built on bubbletea (already a dependency for the
app-status TUI).

- shared/ui: SelectFromList keeps its (int, string, error) contract; new
  SelectOption covers short fixed menus; new PromptInput replaces
  promptui.Prompt (defaults pre-fill the field, validation on submit).
- Long lists scroll with a 'type / to filter' hint; filtering is fuzzy.
- Prompt aborts (Ctrl+C/Esc) surface as ui.ErrPromptInterrupted; the error
  handler matches it structurally (errors.Is) so %w-wrapped aborts still
  print the friendly 'cancelled by user' notice instead of an error panel.
- Wizard steps, cluster/chart mode selects and the typed-name delete
  confirmation now go through the shared prompt helpers; promptui and
  chzyer/readline (with its version excludes) drop out of go.mod entirely.

Verified under a PTY harness: picker select/arrows//-filter, Ctrl+C abort,
and the full create wizard in --dry-run all complete and exit cleanly.
promptui is gone from the module graph; interactive prompts now run on
charmbracelet/huh over bubbletea (which also powers the app status TUI).
…t height

Interactive prompts now refuse to start when the session is non-interactive
(CI env or non-TTY stdin), matching the RequireConfirmation contract. On Unix
CI this was already the effective behavior - bubbletea cannot open /dev/tty
there - but Windows runners DO have a console, so a prompt reached in tests
blocked on ReadConsole until the 10-minute job timeout
(TestWizardSteps_ConfirmConfiguration on windows-amd64).

Also size long-list selects correctly: huh's Height includes the title and
description rows, so selectPageSize+2 - not +3 - shows exactly ten option
rows (CodeRabbit flagged the mismatch; its literal suggestion of +0 would
have shown eight).
…otations

One central hook (ApplyStatusPrefixTheme, wired into ApplyGlobalOutputFlags)
re-themes the package-level pterm printers every call site prints through:

- Interactive terminals drop the block badges for quiet glyph prefixes from
  the shared GlyphSet (dim bullet for info, triangle/cross/check for
  warning/error/success), inheriting its ASCII fallback.
- Non-interactive output (CI, pipes, --plain) keeps word tags for
  grep-ability but lowercase, column-aligned and foreground-colored:
  info/warning/error/success/debug, no background blocks.
- Inside GitHub Actions, warnings are teed into ::warning:: annotations so
  they surface on the PR; errors already got richer annotations from the
  shared error handler, which now also stops prepending a manual failure
  glyph the themed prefix carries.

--silent still wins (theme runs after the flag handlers), NO_COLOR degrades
to plain glyph/tag text via the existing color contract.
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0ff1fad1-d273-4968-b5fe-f8a44f9c5568

📥 Commits

Reviewing files that changed from the base of the PR and between f1a4b9f and 3ae0ced.

📒 Files selected for processing (9)
  • cmd/app/status.go
  • cmd/app/upgrade.go
  • internal/chart/providers/argocd/wait.go
  • internal/chart/services/cluster.go
  • internal/cluster/providers/eks/teardown.go
  • internal/cluster/providers/gke/teardown.go
  • internal/shared/ui/silent.go
  • internal/shared/ui/status_theme.go
  • internal/shared/ui/status_theme_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • internal/shared/ui/status_theme.go
  • internal/shared/ui/status_theme_test.go

📝 Walkthrough

Walkthrough

The change adds configurable status prefixes and GitHub Actions annotations, applies timestamp and theme settings during global output setup, updates generic error rendering, and changes several status and progress messages to avoid repeated labels and indentation.

Changes

Status output handling

Layer / File(s) Summary
Status theme and annotation pipeline
internal/shared/ui/status_theme.go, internal/shared/ui/ghactions.go, internal/shared/ui/status_theme_test.go
Status printers use interactive glyphs or aligned non-interactive severity labels. GitHub Actions warnings are sanitized and deduplicated. Tests cover formatting, restoration, prefix removal, and annotations.
Global output and shared error formatting
internal/shared/ui/silent.go, internal/shared/errors/errors.go
Verbose mode timestamps all status printers and exposes timestamp state. Global setup applies the status theme. Generic errors use the themed error prefix.
Application and resource message formatting
internal/chart/providers/argocd/wait.go, cmd/app/status.go, cmd/app/upgrade.go, internal/chart/services/cluster.go, internal/cluster/providers/eks/teardown.go, internal/cluster/providers/gke/teardown.go
Argo CD wait messages route through selected printers and conditionally show heartbeat timestamps. Individual list entries use basic text. Status cause output uses an aligned label.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant ApplyGlobalOutputFlags
  participant ptermStatusPrinters
  participant waitNote
  participant annotationWriter
  participant GitHubActions
  CLI->>ApplyGlobalOutputFlags: apply verbose and output flags
  ApplyGlobalOutputFlags->>ptermStatusPrinters: enable timestamps and apply status theme
  waitNote->>ptermStatusPrinters: route formatted status message
  ptermStatusPrinters->>annotationWriter: write warning output
  annotationWriter->>GitHubActions: emit sanitized warning annotation
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main UI status-prefix restyling and GitHub Actions warning annotation changes.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/status-prefix-restyle

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

ivan-flamingo
ivan-flamingo previously approved these changes Aug 5, 2026
@oleg-flamingocx
oleg-flamingocx enabled auto-merge (squash) August 5, 2026 17:05
The Actions runner echoes every ::warning:: workflow command inline in the
log, so the ArgoCD wait's recurring stuck-app summary produced a doubled,
unstyled 'Warning:' line next to each themed one, every cycle - and GitHub
keeps only 10 annotations per step, so repeats crowded out new warnings.
The annotation tee now emits each distinct message once per process.

Also drop the manual two-space indent from the wait loop's pending/stuck/
hint messages: it predates the aligned prefix tags, which now hold the
column on their own - the indent just made rows ragged. Deliberately nested
verbose detail (per-app drill-down) keeps its deeper indentation.

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/shared/ui/status_theme.go`:
- Around line 71-73: Update the waitNote warning path to use the warning-aware
annotation writer configured by ApplyStatusPrefixTheme(), rather than dash.Note
or pterm.DefaultBasicText.Println(). Ensure ArgoCD wait warnings emit a
deduplicated WarningAnnotation once per distinct waiting issue while preserving
existing behavior for non-warning messages.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 36a04794-67f0-43d3-8080-ff9408fb9fd1

📥 Commits

Reviewing files that changed from the base of the PR and between 42397fb and f1a4b9f.

📒 Files selected for processing (6)
  • internal/chart/providers/argocd/wait.go
  • internal/shared/errors/errors.go
  • internal/shared/ui/ghactions.go
  • internal/shared/ui/silent.go
  • internal/shared/ui/status_theme.go
  • internal/shared/ui/status_theme_test.go

Comment thread internal/shared/ui/status_theme.go
The verbose ArgoCD wait intro printed its explanation as debug lines with a
manual '  - ' indent, and several list sites (orphan GKE disks / EBS
volumes, verbose cluster list, out-of-sync apps, unreachable-cluster cause)
stamped a status tag on every item. With the aligned prefix tags the manual
indents read as ragged columns, and a tag per list item is noise.

Intro lines lose the dash indent (each timestamped debug line stands on its
own); list items under a tagged header now go through DefaultBasicText —
the repo's existing header+items pattern (see ShowCleanupSummary) — and the
unreachable-cluster cause row mirrors the shared error panel's dim-key
style. Deliberately nested verbose drill-downs keep their indentation.
waitNote took a pre-styled string and printed it via DefaultBasicText, so
the ArgoCD wait's warnings (repo-server not recovering, apps stuck in
Unknown, stall-sync failures) looked like warnings but bypassed
pterm.Warning's writer — where the CI ::warning:: annotation tee lives —
and never surfaced as PR annotations.

waitNote now takes the status printer plus the raw message: the
non-dashboard path prints through that printer (annotation tee included);
the dashboard path still pins the styled line under the live area and never
annotates, but it only runs on interactive terminals — CI always takes the
printer path.
Two defects in the annotation tee's prefix stripping:

- Under NO_COLOR pterm's RawOutput mode renders the tag as 'warning: msg';
  the strip list only knew the bare word, so a leading colon leaked into
  the annotation text.
- Prefixes were stripped sequentially without a boundary, so after
  removing 'warning' the loop would also eat a message-initial 'error'
  ('warning  errors found' -> 's found'). No current call site hits this,
  but it was latent.

Strip exactly one marker (break on first match) and drop RawOutput's
trailing colon after the matched prefix.
yaroslavmokflmg
yaroslavmokflmg previously approved these changes Aug 5, 2026
--verbose exists to correlate CLI actions with cluster events, but only
Debug lines carried the wall clock: info/warning rows in the same stream
were clock-less and their message column sat 13 characters to the left of
every debug row. All five status printers now share one timestamp writer
(single line-start state), so a verbose run reads as one aligned timeline.

The ArgoCD wait heartbeat keeps its own embedded [clock] ONLY when the
writer is not stamping lines (plain CI logs, where it is the sole time
reference) — under --verbose it drops it instead of printing two clocks on
one row (ui.TimestampsActive). CI annotations are unaffected: the tee sees
rendered text before the clock is prepended.
@oleg-flamingocx
oleg-flamingocx merged commit 4b91628 into main Aug 5, 2026
12 of 14 checks passed
@oleg-flamingocx
oleg-flamingocx deleted the feat/status-prefix-restyle branch August 5, 2026 21: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.

3 participants