Diversio Engineering
On this page
PI PACKAGE EXTENSION

Pi Timestamps

Subtle per-turn transcript timing rows for exact timestamps, reply-start timing, timezone-aware absolute times, and live relative-age labels.

Overview

Subtle per-turn transcript timing rows for exact timestamps, reply-start timing, timezone-aware absolute times, and live relative-age labels.

Package docs also remain available on the package summary page at /docs/pi-timestamps, but this page focuses on the Pi-native extension surface: commands, tools, environment variables, packaged skills, and extension files.

Environment

  • If PI_TIMESTAMPS_TIME_ZONE is unset, the extension uses your local system timezone.
  • PI_TIMESTAMPS_TOGGLE_SHORTCUT changes both the registered shortcut and the inline hint text.
  • PI_TIMESTAMPS_LIVE_RELATIVE=false disables the bottom-status ... ago ticker for a maximally stable UI.
  • export PI_TIMESTAMPS_TIME_ZONE="America/Toronto"
  • export PI_TIMESTAMPS_TOGGLE_SHORTCUT="ctrl+shift+h"
  • export PI_TIMESTAMPS_LIVE_RELATIVE="false"
  • PI_TIMESTAMPS_LIVE_RELATIVE=false

Extension Files

Primary extension path: pi-packages/pi-timestamps/extensions/pi-timestamps

  • index.ts

Installation

bash
pi install "$PWD/pi-packages/pi-timestamps"

Problem

Pi already knows when messages happened, but the default transcript does not make that timing easy for a human to scan.

In practice, people want simple answers to simple questions:

  • When did I send that prompt?
  • How long did the model take to start replying?
  • How long did the full turn take?
  • How long ago did the last reply happen?

Solution

pi-timestamps adds one small, subtle timing row after each user prompt.

Most turns show normal timing data. If no visible assistant reply arrives, the row falls back to reply incomplete instead of pretending the turn completed normally.

Visual design principles:

Current highlighting:

Labeling note:

Mental model:

Example row:

Example status line snippets:

  • keep the row quiet enough that it does not compete with the transcript
  • still make the important timing fields pop
  • use color intentionally instead of making the whole row loud
  • completion time uses a success color
  • reply in and total values use an accent color
  • the hide shortcut stays dimmer than the timing data
  • the bottom status line keeps the flavor text dimmer
  • the live relative age in the bottom status bar is the part that pops most
  • we use reply in, not thought for
  • reply in means: "how long until visible answer text appeared"
  • that is a user-experience metric, not an internal reasoning metric
text
user sends prompt
   ↓
extension records start time
   ↓
first visible assistant text appears
   ↓
extension records reply-start timing
(or falls back to assistant-start timing if no text-start event arrives)
   ↓
turn fully ends
   ↓
extension appends one tiny display-only timing row
text
2026-06-02 19:18:01 EDT · done 2026-06-02 19:18:08 EDT · reply in 3s · total 7s · hide row: ctrl+shift+h

Why it works this way

Because Pi's current extension API can render custom extension messages, but it does not let us rewrite the built-in user/assistant chat bubbles directly.

So the extension does this instead:

That keeps the feature reliable without patching Pi core.

We tried that. It felt too noisy.

The current design aims for:

A changing 11s ago label inside historical transcript rows forces Pi to rerender old chat lines. That is fragile when you have scrolled up and are trying to read a long response.

So the extension now keeps transcript rows static and moves only the newest relative age to the bottom status bar.

The ticker is still adaptive instead of repainting once per second forever:

  • low visual weight
  • useful timing at a glance
  • no persistent second panel competing with the conversation
text
normal Pi transcript row
normal Pi transcript row
small timing row added by the extension
text
first minute  -> update every second  -> 11s ago, 12s ago, ...
first hour    -> update every minute  -> 2m ago, 3m ago, ...
after that    -> update hourly        -> 2h ago, 1d ago change slowly

What gets shown

Each timing row can show:

The bottom status bar shows playful Yoda-ish lines for the newest turn. While the model is working it rotates through in-progress messages; after completion it rotates through replied/fumbled messages and appends the newest relative age. The flavor text stays relatively dim while the age label is the colorful part that stands out.

Animations come from a pool of ten. On session start an animation is chosen, and each new human message re-rolls the animation for the next turn. The little Yoda-ish bot nickname now shuffles along with the status text itself instead of getting stuck for a whole turn. For now, the football-themed animations are weighted more heavily through July 19.

Visual map:

  • exact prompt timestamp
  • exact completion timestamp
  • reply-start timing when visible text appeared
  • fallback assistant-start timing if the provider does not emit a text-start event
  • total turn duration
  • inline "hide row" shortcut text
text
2026-06-02 19:18:01 EDT · done 2026-06-02 19:18:08 EDT · reply in 3s · total 7s · hide row: ctrl+shift+h
│                        │                              │             │          └─ quick hide-row hint
│                        │                              │             └─ full turn duration
│                        │                              └─ time until the reply became visible
│                        └─ exact completion time
└─ exact prompt time

status: 🥾⚽ Cooking, the tin monk is. Glass, tap not.
status: ⚽ 11s ago · Replied, the tin monk has. Your move, captain.