Skip to content

fix: quit pvt tui cleanly#2

Merged
OneNoted merged 14 commits intomainfrom
fix-quit-pvt-tui-cleanly
Mar 19, 2026
Merged

fix: quit pvt tui cleanly#2
OneNoted merged 14 commits intomainfrom
fix-quit-pvt-tui-cleanly

Conversation

@OneNoted
Copy link
Copy Markdown
Owner

Summary

  • wire Vaxis loop pointers only after App is at its final address
  • restore the terminal through a fast quit path instead of relying on loop.stop()
  • exit the TUI subprocess immediately after terminal restore on normal quit

Verification

  • rebuilt vitui with cd tui && zig build -Doptimize=ReleaseSafe
  • launched ./pvt tui, pressed q, and verified the terminal restored and the process exited with code 0
  • verified vitui --help resolves from PATH after local install

Zig-based terminal UI (libvaxis) that reads pvt.yaml and provides
four live views: Cluster status, Storage pools, Backups (PVE + K8s),
and Performance metrics (PromQL).

- Config parsing with env var expansion and duration strings
- Proxmox REST API client via curl subprocess (handles tls_verify: false)
- Talos client via talosctl subprocess with JSON parsing
- Kubernetes client via kubectl for VolSync/Velero backup detection
- Metrics client with Prometheus/VictoriaMetrics autodetection
- Background polling with mutex-protected shared state
- Vim-style navigation (hjkl, /, gg/G) across all views
- Storage usage bars with configurable warn/crit thresholds
- Backup stale flagging with confirmation dialog for deletion
- Search/filter overlay in backups view
- Pod metrics sortable by CPU/memory/network, filterable by namespace
- Help overlay with view-specific keybinding hints
Searches for the vitui binary adjacent to pvt, in tui/zig-out/bin/,
or in $PATH. Forwards --config flag and inherits stdio for seamless
terminal passthrough.
Config strings from the YAML parser were slices into the source buffer
which was freed at the end of load(). All string fields now duped via
allocator so they survive yaml.deinit().

Also fix PVE API auth header to include token_id in the format
PVEAPIToken=<token_id>=<token_secret> as required by the Proxmox API.
When --config isn't explicitly set, pvt tui now passes viper's
resolved config file path to vitui so it can find pvt.yaml without
the user having to specify it manually.
- Expand ~ to $HOME in config string values so paths like
  ~/talos/apollo/talosconfig resolve correctly
- Remove std.log.err() calls from HTTP client that wrote to stderr
  and corrupted the vaxis TUI rendering
- Fix q key quit by calling loop.stop() and checking should_quit
  immediately after event handling
Don't call loop.stop() from inside the event handler — it corrupts
the loop state causing a NULL pointer memcpy crash. Instead just set
should_quit and break from the event loop, then call exitAltScreen
before deinit for clean terminal restoration.
The poller thread can be blocked for up to 10s on a curl timeout or
30s on its sleep interval. Previously deinit() called poller.stop()
(which joins the thread) before restoring the terminal, leaving the
user staring at a frozen screen. Now: signal stop, restore terminal,
then join.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 04d44f2fd4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tui/src/poll.zig Outdated
Comment thread tui/src/views/backups.zig Outdated
Comment thread tui/src/config.zig Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a7ff553b1d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tui/src/app.zig
Comment thread tui/src/api/proxmox.zig Outdated
Comment thread tui/src/api/metrics.zig
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d8bc417449

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tui/src/views/performance.zig
Comment thread tui/src/poll.zig Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5b5dcd6e67

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tui/src/app.zig Outdated
Comment thread tui/src/views/backups.zig Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 76f8f54ead

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tui/src/views/performance.zig Outdated
Comment thread tui/src/views/performance.zig
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ccba27fd43

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tui/src/views/backups.zig
Comment on lines +172 to +174
for (backups) |b| {
if (!self.matchesFilter(b, filter)) continue;
if (current_row >= win.height -| 1) break;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Implement backup list scrolling before rendering rows

The backups renderer always iterates from the beginning of backups and only stops when it reaches the window bottom, but it never applies a viewport offset from self.scroll. When the filtered list is taller than the view, moving selection past the first screenful leaves no visible selected row, yet d still acts on the off-screen index, making deletion targeting easy to misread. Add scroll-window logic (like the performance/storage views) so rendering starts from the current scroll position.

Useful? React with 👍 / 👎.

@OneNoted OneNoted merged commit 0cebebc into main Mar 19, 2026
1 check passed
@OneNoted OneNoted deleted the fix-quit-pvt-tui-cleanly branch March 19, 2026 11:56
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.

1 participant