feat(ui): optional last-update timestamp badge on session rows#1165
Draft
rodrimendoza wants to merge 1 commit into
Draft
feat(ui): optional last-update timestamp badge on session rows#1165rodrimendoza wants to merge 1 commit into
rodrimendoza wants to merge 1 commit into
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
1d3e79e to
a906e85
Compare
Adds an opt-in dim "Nm ago" / "Nh ago" / "Nd ago" badge after each
session row, controlled by [display] show_session_timestamps in
config.toml (default off, toggle in Settings → DISPLAY).
The badge picks the newest of, in order:
1. Instance.CreatedAt (SQLite, persisted floor)
2. Instance.LastStartedAt (SQLite, lifecycle restart)
3. Latest hook event UpdatedAt (StatusFileWatcher, present when
agent-deck hooks are installed
in Claude/Codex settings)
4. Confirmed tmux activity time (tmux.StateTracker.lastChangeTime,
gated on a new realActivityConfirmed
flag so freshly-built trackers
don't falsely report "just now"
for every session post-restart)
LastAccessedAt is deliberately excluded: attaching to a quiet session
to peek at it isn't an "update", and including it made the badge lie.
Why a new flag in tmux.StateTracker?
Naively reading lastChangeTime doesn't work — tmux.go initializes it
to time.Now() at tracker construction, so right after agent-deck
starts every session reports "just now" regardless of how long it's
actually been idle. The flag flips true only at the explicit-busy
confirmation paths in Session.GetStatus and getStatusFallback (grep
realActivityConfirmed = true), never at construction. Callers
consult the bool before consuming the time.
Performance: render-path cost per row per tick is two in-memory
accessor calls (hook watcher map + tmux confirmed activity) plus a
handful of time.Time comparisons. No new I/O, no new goroutines.
The StatusFileWatcher already runs for hook status display.
Persistence: the toggle is added to MergePanelConfigOntoDisk's
allowlist (issue asheshgoplani#1067) so it actually round-trips; the cached value
on Home is refreshed immediately after the panel saves, so the
toggle takes effect without a restart.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
a906e85 to
baa7dd8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in dim
Nm ago/Nh ago/Nd agobadge after each session row, showing the most recent of:Instance.CreatedAt(SQLite, persisted floor)Instance.LastStartedAt(SQLite, lifecycle restart)UpdatedAt(StatusFileWatcher, present when agent-deck hooks are installed in Claude/Codex settings)StateTracker.lastChangeTime, gated on a newrealActivityConfirmedflag so freshly-built trackers don't falsely report "just now" for every session after restart)The formula lives in
pickBadgeTime(pure function) so it's unit-testable in isolation.LastAccessedAtis deliberately excluded — attaching to a quiet session to peek at it isn't an "update", and including it made the badge lie.No pre-existing issue — happy to file one and discuss the design first if preferred.
Screenshots
Settings menu — toggle on (off by default)
Sessions list with the badge enabled
Why a new
realActivityConfirmedflag intmux.StateTracker?Naively reading
lastChangeTimeis the obvious first attempt and was where I started. It doesn't work becausetmux.goinitializeslastChangeTime = time.Now()at tracker construction — so right after agent-deck starts, every session reports "just now" regardless of how long it's actually been idle.The flag flips
trueonly at the explicit-busy confirmation paths insideSession.GetStatusandSession.getStatusFallback(git grep 'realActivityConfirmed = true'), never at construction. Callers consult the bool before consuming the time value, so the "never observed" case falls back to the lifecycle floor.How to enable
Settings → DISPLAY → Show session timestamps (default off). Persisted as
[display] show_session_timestamps = true. Toggle takes effect immediately, no restart.Risk
Render-path cost per row per tick: two in-memory accessor calls (hook watcher map + tmux confirmed activity) plus a handful of
time.Timecomparisons. No new I/O, no new goroutines. TheStatusFileWatcheralready runs for hook status display.Test plan
go build ./...cleanrealActivityConfirmedflag (false at init, true after confirmation, zero-time sentinel when unobserved), the fullpickBadgeTimeformula across all 4 layers with nil/zero/unobserved edges,LastAccessedAtexclusion, niltmuxSessionsafety, merge round-trip, settings-panel scroll mapping reaches the new row🤖 Generated with Claude Code