Skip to content

feat(tui): add configurable reply timestamps - #62530

Open
NachiketKandari wants to merge 2 commits into
anomalyco:devfrom
NachiketKandari:reply-timestamps
Open

NachiketKandari wants to merge 2 commits into
anomalyco:devfrom
NachiketKandari:reply-timestamps

Conversation

@NachiketKandari

@NachiketKandari NachiketKandari commented Nov 7, 2026 •

Copy link
Copy Markdown

Issue for this PR

Related to #53192

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Adds optional wall-clock timestamps to assistant footers in the TUI.

v2 already shows the response duration and tokens/sec, but it has no equivalent of v1's /timestamps for assistant replies. This adds two opt-in cli.json settings:

  • session.timestamps (default false): show the reply's completion time and date.
  • session.date_format (default "locale"): locale, friendly (Nov 6, 2026), dd-mon-yyyy (06-Nov-2026), or iso (2026-11-06).

Both appear in Ctrl+P → Settings. The timestamp is based on message.time.completed, so it only appears after a reply finishes; a streaming reply does not show its start time as the completion time.

Build · Claude Sonnet · 15.8s · 42.3 tok/s · 9:41 PM · 06-Nov-2026

The formatter is in Locale.date. The feature is off by default, so existing configs are unchanged.

How did you verify your code works?

  • bun test test/config-v2.test.tsx test/util/locale.test.ts — 28 pass.
  • bun test --timeout 30000 test/app-lifecycle.test.tsx -t "keeps assistant footer metrics" — pass, including the rendered dd-mon-yyyy timestamp.
  • bun check on the changed files — no errors from this change.
  • bun run lint — no warnings or errors in the changed files.
  • Tests cover all four date formats and the default-off config.

Visual

<svg xmlns="http://www.w3.org/2000/svg" width="240" height="72" viewBox="0 0 240 72" fill="none">
  <style>
    text { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
    .muted { font-size: 9px; fill: currentColor; opacity: .45; }
    .value { font-size: 9px; fill: currentColor; opacity: .9; }
  </style>
  <rect x="0.5" y="0.5" width="239" height="71" rx="6" stroke="currentColor" opacity=".18"/>
  <text x="12" y="22" class="muted">Build · Claude Sonnet · 15.8s · 42.3 tok/s</text>
  <text x="12" y="40" class="value" opacity="0">
    9:41 PM · 06-Nov-2026
    <animate attributeName="opacity" values="0;0;.9;.9;0" keyTimes="0;.2;.45;.8;1" dur="3s" repeatCount="indefinite"/>
  </text>
  <rect x="12" y="54" width="86" height="3" rx="1.5" fill="currentColor" opacity=".12"/>
  <rect x="12" y="54" height="3" rx="1.5" fill="currentColor" opacity=".4">
    <animate attributeName="width" values="12;86;12" dur="3s" repeatCount="indefinite"/>
  </rect>
</svg>

Screenshots / recordings

The terminal output is shown in the description above.

Notes

This is a feature I use daily. I have been running this patch locally on v2.2.5, and this PR contains only the feature, its tests, and the documentation change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Added by the opencode bot (AI-generated).

Related: #49742, #53192, #62344

Public API: adds optional cli.json keys session.timestamps and session.date_format (backwards compatible)

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The feature works as described. With session.timestamps on, I ran the TUI from source on base and on this branch with the simulated model. The footer changes from Build · Simulated Model · 66ms to Build · Simulated Model · 69ms · 7:54 AM · 07-Nov-2026. The related config, locale and footer tests pass, and the type check shows no new errors.

I couldn't get usable before/after screenshots from my run. Could you add before and after screenshots of the footer with the setting on?

Public API: adds two optional cli.json keys, session.timestamps (boolean, default false) and session.date_format (locale | friendly | dd-mon-yyyy | iso, default locale). Both also appear in Settings. This is backwards compatible: existing configs are unchanged and nothing is removed.

One concern, inline: the timestamp wraps in narrow terminals. Also worth knowing: #49742 asks for v1's per-message timestamps back, including on user messages and the /timestamps toggle, and has a design discussion with other contributors. This change only adds timestamps to assistant footers, so it covers part of that request.

Related: #49742, #53192, #62344

<Show when={config.data.session.tps && tokensPerSecond()}>
{(value) => <span style={{ fg: theme.text.muted }}> · {value().toFixed(1)} tok/s</span>}
</Show>
<Show when={config.data.session.timestamps && timestamp()}>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The model name and duration on this line hide themselves below set terminal widths, but the timestamp doesn't. At 50 columns the footer wraps:

Build · Simulated Model · 51ms · 7:54 AM ·
07-Nov-2026

Could it get a width check too, e.g. dropping the date first and then the time as the terminal gets narrower?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 1168403. The width check now measures the footer parts, accounts for the scrollbar gutter, and drops the whole date first, then the whole time. tok/s is also hidden when the line no longer fits, and a resize regression test covers the exact column where the date drops. Screenshots are in the PR comment above.

Add session.timestamps to show the completion time and date in assistant footers, with session.date_format choosing locale, friendly (Nov 6, 2026), dd-mon-yyyy (06-Nov-2026), or ISO. The feature is off by default.
Account for the scrollbar gutter and hide tokens/sec when the footer line no longer fits, so the date and time drop as whole units instead of their last words wrapping.
@NachiketKandari

Copy link
Copy Markdown
Author

Screenshots

Captured from the actual TUI renderer with session.timestamps: true and session.date_format: "dd-mon-yyyy".

Before — timestamps off

Before

After — timestamps on

After

Narrow terminals

The timestamp now drops the whole date first, then the whole time, instead of letting the terminal wrap it:

Time only Hidden
Time only Hidden

The width check also accounts for the scrollbar gutter, and hides tok/s when the footer line no longer fits, so the footer does not wrap at the boundary. A regression test covers the exact column where the date drops.

Scope note: this remains intentionally limited to assistant reply footers; per-message timestamps and the /timestamps toggle from #49742 are not part of this change.

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

My earlier concern is resolved: the footer no longer wraps in narrow terminals. I ran the branch from source with the simulated model at 120, 60, 50, 48 and 40 columns. The full timestamp shows when it fits. Narrower, the date drops and then the time, and the line stays on one row. The footer tests, including the new resize test, and the config and locale tests pass.

Public API: same as before. Adds the optional cli.json keys session.timestamps (boolean, default false) and session.date_format (locale | friendly | dd-mon-yyyy | iso, default locale). This is backwards compatible.

One behaviour change to be aware of: with tps on, tok/s now hides when it wouldn't fit, even if timestamps are off; before, it wrapped onto a new line. That seems reasonable. No other concerns.

Related: #49742, #53192, #62344

Before

After

@gvtret

gvtret commented Nov 11, 2026

Copy link
Copy Markdown

+1 — this is the one v2 feature I miss daily.

Use case: long working sessions (often hours) in the TUI, where I need to correlate what the agent did with external events — server logs, CI runs, deploy times. The transcript currently tells me what happened and how long each turn took, but not when it happened. Post-hoc debugging today means exporting the session and scripting over time.created with jq, which is exactly what this PR removes.

The opt-in design looks right to me: session.timestamps off by default keeps the footer clean, and the four session.date_format options cover both human-readable and ISO needs (the ISO one is handy for pasting into tickets and logs). Also glad it lands in Ctrl+P → Settings, mirroring v1's /timestamps discoverability (#49742).

Would really appreciate seeing this merged. Happy to help test it on a long-running session if a review build is published.

This branch has not been deployed

No deployments
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.

2 participants