Skip to content

feat(execution-history): restore parity gaps from the old runs UI - #21

Merged
aryasaatvik merged 2 commits into
devfrom
feat/runs-parity-gaps
Jun 14, 2026
Merged

feat(execution-history): restore parity gaps from the old runs UI#21
aryasaatvik merged 2 commits into
devfrom
feat/runs-parity-gaps

Conversation

@aryasaatvik

Copy link
Copy Markdown
Owner

What

Restores the user-facing affordances the execution-history plugin dropped when it replaced the old observability runs UI (a952d08ad). Scoped from a full old-vs-new audit; Groups A + B (all client-side — no API/store changes).

Timestamps

  • HoverCardTimestamp (new) — hovering a timestamp reveals epoch / UTC / local-tz / relative renderings, each click-to-copy. On the list-row started cell (keeps its relative-time display) and the drawer's Started/Completed. Native Date/Intl, reusing the shared Radix HoverCard (no date-fns).

List

  • Log column — optional column counting [error]/[warn] lines from the row's logsJson (off by default; toggle in view options). Case-insensitive.
  • Slow-run highlight — durations > 5s render in the destructive color.
  • Code preview widened 80 → 160 chars.
  • Toolbar row count ("N of M"); end-of-history footer; empty-state hint line.

Filters / controls

  • Last 15m time-range preset; title hints on Live/Refresh buttons.

Chart

  • Seconds-resolution axis + tooltip for sub-minute buckets; tooltip escapes the view box and ignores pointer events.

Persistence

  • Column visibility persists across reloads (localStorage, comma-joined keys — no JSON.parse).

Deferred (called out, not done here)

  • Filter-state persistence — needs a RunsFilters schema (the repo lints against JSON.parse) and is better paired with URL params for shareability.
  • tool: / code: / duration_ms: filters + Tools facet — these need API + store changes (cross-collection tool faceting especially), so they belong in a separate PR next to the data work.

Verification

oxfmt --check, oxlint, turbo typecheck (9 packages), plugin tests (17) all pass. UI-only; no API, store, or event-contract changes — independent of the in-flight data/actor work.

Port the user-facing affordances the plugin dropped when it replaced the
old observability runs UI — all client-side, no API/store changes.

- HoverCardTimestamp: hovering a timestamp (list-row started cell + drawer
  Started/Completed) reveals epoch / UTC / local-tz / relative renderings,
  each click-to-copy. Native Date/Intl; reuses the shared Radix HoverCard.
- Log column: optional list column counting [error]/[warn] lines from the
  row's logsJson (off by default, toggle in view options).
- Slow-run highlight: durations over 5s render in the destructive color.
- Code preview widened 80 -> 160 chars.
- Live/Refresh buttons gain title hints; "Last 15m" time-range preset.
- Toolbar row-count ("N of M"); empty-state hint line; end-of-history footer.
- Timeline chart: seconds-resolution axis + tooltip for sub-minute buckets;
  tooltip escapes the view box and ignores pointer events.
- Column visibility persists across reloads via localStorage.

Filter-state persistence and the tool:/code:/duration_ms: filters are
deferred — they need a filter schema and API/store work respectively.
@greptile-apps

greptile-apps Bot commented Jun 14, 2026

Copy link
Copy Markdown

Greptile Summary

This PR restores a set of UI affordances dropped from the old runs page: a HoverCardTimestamp component with click-to-copy epoch/UTC/local/relative values, a log error/warn count column, slow-run highlighting, sub-minute chart resolution, column-visibility persistence in localStorage, row-count display, "End of history" footer, and a "Last 15m" time preset.

  • HoverCardTimestamp is a self-contained new component using only native Date/Intl; closeDelay={150} addresses the previous review concern about premature card close.
  • Column persistence uses a comma-joined key=0|1 format (no JSON.parse), and readStoredColumns correctly seeds from DEFAULT_COLUMNS before applying stored values, so future new columns keep their defaults for existing users.
  • All changes are UI-only with no API, store, or event-contract modifications.

Confidence Score: 5/5

Safe to merge — all changes are purely client-side UI with no API, store, or event-contract modifications.

Every changed file is UI-only. The column persistence logic correctly merges stored values over DEFAULT_COLUMNS so new columns never silently inherit hidden state for existing users. The HoverCardTimestamp component is well-isolated, uses only native APIs, and the portal-rendered content avoids any nested-interactive-element issues. The only finding is a stale outer comment on readStoredColumns that contradicts the implementation — the code itself behaves correctly.

No files require special attention beyond the comment fix in RunsPage.tsx.

Important Files Changed

Filename Overview
packages/plugins/execution-history/src/react/RunsPage.tsx Adds column-visibility persistence (localStorage, comma-join format) and a row-count display. The read logic correctly merges stored values over DEFAULT_COLUMNS so future new columns keep their defaults; the outer comment above the function contradicts the implementation.
packages/plugins/execution-history/src/react/hover-card-timestamp.tsx New component — hover reveals epoch/UTC/local-TZ/relative renderings with click-to-copy. closeDelay set to 150ms (previous review concern addressed). Click propagation stopped correctly on CopyRow; portalled HoverCardContent avoids nested-button HTML issues.
packages/plugins/execution-history/src/react/run-row.tsx Adds HoverCardTimestamp for the Started cell, log error/warn counts column (gated by columns.log), and slow-run destructive highlight for durationMs > 5000. Log parsing is lazy (skipped when column is off). Code preview widened to 160 chars.
packages/plugins/execution-history/src/react/detail-drawer.tsx Started and Completed MetaCards now use HoverCardTimestamp. Null-completedAt branch falls back to formatDateTime(null) which returns "Pending" — correct and type-safe.
packages/plugins/execution-history/src/react/timeline-chart.tsx Seconds-resolution axis/tooltip for sub-minute buckets (≤60 000 ms); tooltip escape and pointer-events fix are straightforward Recharts prop additions.
packages/plugins/execution-history/src/react/shell.tsx Adds "End of history" footer when !hasMore && !isLoadingMore. Correctly guarded inside the !isEmpty branch so it never shows when the empty state is displayed.
packages/plugins/execution-history/src/react/filter-rail.tsx Adds a "Last 15m" preset (15 * 60 * 1000 ms) at the head of TIME_RANGE_PRESETS. Straightforward and correctly ordered.
packages/plugins/execution-history/src/react/view.ts Adds the "log" column key with default false to RunColumns, DEFAULT_COLUMNS, and RUN_COLUMN_LABELS. All three locations updated consistently.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[RunsPage mount] --> B[readStoredColumns]
    B --> C{localStorage has\nexecutionHistory.columns?}
    C -- No --> D[Return DEFAULT_COLUMNS]
    C -- Yes --> E[Seed next from DEFAULT_COLUMNS]
    E --> F[Override only stored key=value pairs]
    F --> G[New columns keep default visibility]
    G --> H[columns state initialized]
    H --> I[useEffect: columns changed]
    I --> J[serializeColumns → write to localStorage]

    H --> K[RunListRow render]
    K --> L{columns.log?}
    L -- Yes --> M[logLines logsJson\ncount errors/warns]
    L -- No --> N[logs = empty array]
    M --> O[Display Log column with E/W counts]

    K --> P[HoverCardTimestamp timestamp=startedAt]
    P --> Q{Hover?}
    Q -- Yes --> R[Show epoch / UTC / local / relative\neach click-to-copy]
    Q -- No --> S[Show formatRelative display]

    K --> T{durationMs > 5000?}
    T -- Yes --> U[text-destructive]
    T -- No --> V[text-muted-foreground]
Loading

Fix All in Codex Fix All in Cursor Cloud Agents Fix All in Claude Code Fix All in Cursor

Reviews (2): Last reviewed commit: "fix(execution-history): address drawer p..." | Re-trigger Greptile

Comment thread packages/plugins/execution-history/src/react/hover-card-timestamp.tsx Outdated
Comment thread packages/plugins/execution-history/src/react/RunsPage.tsx
- HoverCardTimestamp: closeDelay 0 -> 150ms so the cursor can travel from
  the trigger to the copy rows without the card closing (Radix HoverCard has
  no safe-polygon grace area).
- Column persistence stores explicit key=0/1 pairs and reads unknown keys
  from DEFAULT_COLUMNS, so a column added in a later release keeps its
  default visibility instead of being locked hidden for existing users.
@aryasaatvik
aryasaatvik merged commit 1d6ef75 into dev Jun 14, 2026
10 of 13 checks passed
@aryasaatvik
aryasaatvik deleted the feat/runs-parity-gaps branch June 14, 2026 21:11
aryasaatvik added a commit that referenced this pull request Jun 23, 2026
## What

Restores the user-facing affordances the execution-history plugin
dropped when it replaced the old observability runs UI (`a952d08ad`).
Scoped from a full old-vs-new audit; **Groups A + B** (all client-side —
no API/store changes).

### Timestamps
- **`HoverCardTimestamp`** (new) — hovering a timestamp reveals **epoch
/ UTC / local-tz / relative** renderings, each **click-to-copy**. On the
list-row started cell (keeps its relative-time display) and the drawer's
Started/Completed. Native `Date`/`Intl`, reusing the shared Radix
`HoverCard` (no `date-fns`).

### List
- **Log column** — optional column counting `[error]`/`[warn]` lines
from the row's `logsJson` (off by default; toggle in view options).
Case-insensitive.
- **Slow-run highlight** — durations > 5s render in the destructive
color.
- Code preview widened **80 → 160** chars.
- Toolbar **row count** ("N of M"); **end-of-history** footer;
empty-state hint line.

### Filters / controls
- **`Last 15m`** time-range preset; **title hints** on Live/Refresh
buttons.

### Chart
- **Seconds-resolution** axis + tooltip for sub-minute buckets; tooltip
escapes the view box and ignores pointer events.

### Persistence
- **Column visibility** persists across reloads (localStorage,
comma-joined keys — no `JSON.parse`).

## Deferred (called out, not done here)
- **Filter-state persistence** — needs a `RunsFilters` schema (the repo
lints against `JSON.parse`) and is better paired with URL params for
shareability.
- **`tool:` / `code:` / `duration_ms:` filters + Tools facet** — these
need API + store changes (cross-collection tool faceting especially), so
they belong in a separate PR next to the data work.

## Verification
`oxfmt --check`, `oxlint`, `turbo typecheck` (9 packages), plugin tests
(17) all pass. UI-only; no API, store, or event-contract changes —
independent of the in-flight data/actor work.
aryasaatvik added a commit that referenced this pull request Jun 23, 2026
## What

Restores the user-facing affordances the execution-history plugin
dropped when it replaced the old observability runs UI (`a952d08ad`).
Scoped from a full old-vs-new audit; **Groups A + B** (all client-side —
no API/store changes).

### Timestamps
- **`HoverCardTimestamp`** (new) — hovering a timestamp reveals **epoch
/ UTC / local-tz / relative** renderings, each **click-to-copy**. On the
list-row started cell (keeps its relative-time display) and the drawer's
Started/Completed. Native `Date`/`Intl`, reusing the shared Radix
`HoverCard` (no `date-fns`).

### List
- **Log column** — optional column counting `[error]`/`[warn]` lines
from the row's `logsJson` (off by default; toggle in view options).
Case-insensitive.
- **Slow-run highlight** — durations > 5s render in the destructive
color.
- Code preview widened **80 → 160** chars.
- Toolbar **row count** ("N of M"); **end-of-history** footer;
empty-state hint line.

### Filters / controls
- **`Last 15m`** time-range preset; **title hints** on Live/Refresh
buttons.

### Chart
- **Seconds-resolution** axis + tooltip for sub-minute buckets; tooltip
escapes the view box and ignores pointer events.

### Persistence
- **Column visibility** persists across reloads (localStorage,
comma-joined keys — no `JSON.parse`).

## Deferred (called out, not done here)
- **Filter-state persistence** — needs a `RunsFilters` schema (the repo
lints against `JSON.parse`) and is better paired with URL params for
shareability.
- **`tool:` / `code:` / `duration_ms:` filters + Tools facet** — these
need API + store changes (cross-collection tool faceting especially), so
they belong in a separate PR next to the data work.

## Verification
`oxfmt --check`, `oxlint`, `turbo typecheck` (9 packages), plugin tests
(17) all pass. UI-only; no API, store, or event-contract changes —
independent of the in-flight data/actor work.
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