Skip to content

feat(tui): implement Ratatui invocation timeline widget - #500

Merged
codeZe-us merged 1 commit into
Toolbox-Lab:mainfrom
cold-13:feat/483-timeline-widget
Oct 23, 2026
Merged

codeZe-us merged 1 commit into
Toolbox-Lab:mainfrom
cold-13:feat/483-timeline-widget

Conversation

@cold-13

@cold-13 cold-13 commented Oct 21, 2026

Copy link
Copy Markdown

Description

Implements the invocation timeline of the interactive replay debugger (#483).

grat replay <tx-hash> -i used to print a placeholder message. It now opens a real
Ratatui debugger that replays the transaction and shows the contract invocation
stack of the replay, so nested calls can be inspected frame by frame.

How It Was Done

crates/cli/src/tui/widgets/timeline.rs — the timeline widget:

  • flatten() walks the ContractInvocation tree depth first (pre-order) and returns
    TimelineRows carrying the nesting depth, the is_last sibling flag and the
    invocation itself. The order matches the tree printed by grat trace, so a timeline
    index always points at the same invocation.
  • count() returns the number of frames without allocating, and is used by the key
    handling and the footer so that navigation stays allocation free.
  • render() / render_with_focus() draw the frames inside a bordered panel whose
    title shows the position (Timeline (3/12)). The border is cyan while the timeline
    owns the focus and dark gray otherwise.
  • Every row shows the tree connector (├─ / └─), the execution status (✔ / ✘,
    green / red), the function name and the contract id. Stellar contract ids are 56
    characters long, so long ids are elided in the middle (CBQYN5XZ…MCC5).

crates/cli/src/tui/app.rs — the debugger shell:

  • The transaction is replayed with grat_core::replay::replay_transaction before the
    terminal enters raw mode, so a failing replay keeps the regular terminal output.
  • A TerminalGuard restores raw mode, the alternate screen and the cursor on drop,
    which covers normal exits, I/O errors and panics.
  • The screen is split into a header (transaction hash, network, ledger), the timeline
    panel and a footer (frame counter and key bindings).
  • handle_key supports q / Esc / Ctrl+C to quit and ↑/↓ (or j/k) to move
    the focused frame; TuiState::scroll_offset holds the index of the focused frame
    and is clamped to the timeline bounds.

Issues Encountered (If Any)

Related Issue

Closes #483

How It Was Tested

  • 15 unit tests (cargo test) cover the flattening order and sibling flags, the
    frame counter, the elision of contract ids, the indentation of nested invocations,
    the highlight of the focused frame, the clamping of an out-of-bounds index, the
    empty-timeline message, the quit keys, the navigation bounds and the rendered
    screen content. The widget tests render into a TestBackend and assert on the
    resulting buffer.
  • The code was formatted with rustfmt and compiles without warnings.

Screenshots / Video (If Applicable)

The panel renders as follows (frame 3 of 12 focused):

┌ Timeline (3/12) ─────────────────────────────────────────────┐
│ ▶ ├─ ✔ transfer CBQYN5XZ…MCC5                                │
│   ├─ ✔ mint      CBQYN5XZ…MCC5                                │
│   └─ ✘ swap      CBQYN5XZ…MCC5                                │
└───────────────────────────────────────────────────────────────┘

Render the transaction invocation stack of a replayed transaction in the
interactive debugger instead of printing a placeholder message.

The timeline widget flattens the invocation tree depth first, the same order
used by `grat trace`, and renders every frame with its nesting depth, tree
connector, execution status, function name and elided contract id. The panel
title tracks the focused frame, the focused frame is highlighted and an empty
replay reports that no invocation was recorded.

The debugger now sets up a ratatui terminal, replays the transaction before
entering raw mode and handles the timeline navigation keys, with the terminal
restored on exit.
@mintlify

mintlify Bot commented Oct 21, 2026

Copy link
Copy Markdown

Preview approval required

This pull request comes from a fork, so Mintlify won't build a preview until someone with write access approves commit c04dbbb.

Approve preview

@drips-wave

drips-wave Bot commented Oct 21, 2026

Copy link
Copy Markdown

@cold-13 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Oct 21, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 5c947016-a3ba-474a-b15b-a706dd51c902
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@codeZe-us
codeZe-us self-requested a review October 23, 2026 01:57
@codeZe-us
codeZe-us merged commit 5ed2a7a into Toolbox-Lab:main Oct 23, 2026
1 of 2 checks passed
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.

Implement Ratatui Timeline Rendering Widget for TUI Debugger

3 participants