---
title: Refine the data-view generation timeline display
type: task
status: completed
description: >-
  Second pass on the agent session timeline: float the jump-to-latest control, drop the assistant
  label, render each generation tool call by its identifying fields, and give the share page a
  readable measure on desktop.
base_uri: user:task/league/data-views/refine-generation-timeline-display.md
created_at: '2026-09-09T04:11:14.719Z'
entity_id: 449242fa-5a72-4e4b-90a3-f6aaa486727c
finished_at: '2026-09-09T04:37:30.749Z'
owner_identity_uri: █████████████████████████
priority: Medium
public_read: true
relations:
  - relates [[█████████████████████-████████████-█████-███████-███████████]]
tags:
  - user:tag/league-xo-football.md
updated_at: '2026-09-09T04:37:30.749Z'
visibility_analyzed_at: '2026-11-06T00:17:47.187Z'
---

The agent session timeline now renders every event on one line with the assistant message left whole, and the collapsed row names itself. What remains is the layer above that: making an individual event legible at a glance, and making the share page a document rather than a full-bleed strip.

The timeline component is the public `react-agent-timeline` package, SHA-pinned by league. A change there needs a commit, a push, a pin bump in `package.json`, and `yarn install` before any league surface sees it — see the plan for the loop that was used.

## Plan

### Float the jump-to-latest control

- [x] `.rat-timeline-jump` currently sits in normal flow below the entries list, so it appears and disappears as the reader scrolls and the panel's height changes under them. Position it over the entries body instead — absolute against the timeline, horizontally centred, with margin off the bottom edge near the expand control — so showing and hiding it moves nothing.
- [x] The list is the scroll container and the control must not scroll with it; the positioning context belongs on `.rat-timeline` or a wrapper, not on `.rat-timeline-entries`.

### Drop the assistant label

- [x] `AssistantMessage` renders `labels.assistant` in the label slot. Remove the label and let the row's own treatment carry the meaning: it is the only unclamped, full-ink, prose-wrapped row on the surface. It should read unmistakably as a message without being told.
- [x] The label column is a fixed `min-width` (`$rat_label_width`), so an empty label leaves an indent. Decide whether the assistant row spans the full width instead, and keep it distinct from the one-line rows above and below.
- [x] `test/timeline-event.spec.jsx` asserts the assistant label renders and `DEFAULT_LABELS.assistant` exists. Both need revisiting; if the label word is genuinely unused, remove it from `labels.mjs` rather than leaving a dead entry.

### Render each tool call for what it is

- [x] Today every tool row shows one generic chip: the first matching key from `IDENTIFYING_PARAMETERS` in `entry-shape.mjs`, or the whole parameter object. For league's generation tools that buries the answer — a `search_columns` call shows a full `echo '{"query":...}' | NODE_ENV=sandbox node scripts/...` shell line when what identifies it is the query and the grain.
- [x] The package must not learn league's vocabulary (see its ABOUT.md § Scope). The seam already exists for the NAME — `resolve_tool_name` — so the shape to reach for is a sibling seam for the ARGUMENT, letting a consumer return the fields that identify its own tool. `app/core/view-generation/resolve-generation-tool-name.js` is where league's half would live.
- [x] Work through the generation tool set, not just `search_columns`: `describe_column`, `validate_table_state`, `preview_view`, `run_sql`, `emit`. Read the live share timeline for what each one actually carries.
- [x] Verify against a real run rather than a fixture — a hand-written parameter shape can agree with a wrong reading of the contract.

### Make the share page readable on desktop

- [x] `view-generation-share.styl` lets the masthead run the full window width, so the instruction and the timeline stretch across a wide display and the expanded rows are unreadably long lines. The prose blocks already cap at `68ch`; the timeline and the header do not.
- [x] Give the page a measure and centre it, keeping the data table below free to use the full width — the table is the one element that legitimately needs it.

## Verification

Run the package's `yarn verify` (153 specs, including the one-line and stylesheet checks) and give each new behaviour a negative control that is shown to fail. Then look at it: a locally served share page renders a real 244-entry run with all six event types.
