Skip to content

feat: relative-time timestamp annotations + nil stdin-stat guard - #20

Merged
bsg62 merged 2 commits into
mainfrom
feat/relative-time-and-stdin-guard
Jul 25, 2026
Merged

feat: relative-time timestamp annotations + nil stdin-stat guard#20
bsg62 merged 2 commits into
mainfrom
feat/relative-time-and-stdin-guard

Conversation

@bsg62

@bsg62 bsg62 commented Jul 25, 2026

Copy link
Copy Markdown
Member

Implements two improvements discussed together.

#3 — Relative-time annotations

The iat/exp/nbf display annotations now carry the time remaining or elapsed instead of a bare flag:

  • exp in the future → expires in 14m
  • exp in the past → expired 2h ago
  • nbf in the future → not yet valid, in 5m
  • nbf already valid → no note (the ordinary active state)

humanizeDuration renders the largest whole unit (s/m/h/d), truncating toward zero so output is deterministic and testable. The annotations stay display-only — verification and the exit code remain purely cryptographic, and the --json path is unchanged (raw numeric claims).

#5 — nil stdin-stat guard

readToken discarded the error from os.Stdin.Stat() and dereferenced the result. On a closed/detached stdin Stat() can return a nil FileInfo, panicking at stat.Mode(). It now falls through to the interactive prompt in that case.

Tests

  • New TestHumanizeDuration (table-driven, incl. boundary rounding and negative magnitude) and TestFormatTimestamps_ExpiredShowsElapsed.
  • Updated the existing formatTimestamps tests for the enriched exp/nbf wording; renamed NoAnnotationWhenCurrentlyValidInsideValidityWindow and tightened it to assert the new "expires in" note and the bare already-valid nbf.

Follow-up (not in this PR)

site/index.html's hero example hardcodes (…, expired) and is paired with a generated og.png. A relative duration would drift on a static page and re-rendering the OG image is a separate concern, so the marketing site is intentionally left untouched here.

🤖 Generated with Claude Code

bsg62 and others added 2 commits July 25, 2026 20:57
Enrich the iat/exp/nbf annotations with the time remaining or elapsed
instead of a bare flag: exp now reads "expires in 14m" / "expired 2h ago"
and a future nbf "not yet valid, in 5m". An already-valid nbf stays bare.
humanizeDuration renders the largest whole unit (s/m/h/d), truncating
toward zero so output is deterministic. Annotations remain display-only
and never affect verification or the exit code.

Also guard readToken against a nil FileInfo when os.Stdin.Stat() fails
(closed or detached stdin): it now falls through to the interactive
prompt rather than dereferencing nil and panicking.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update the hero terminal example and regenerate og.png so the exp claim
shows the new relative-time annotation: a live token reading
"expires in 15m" against an iat 15 minutes earlier, paired with the
"Signature: VALID" line. The annotation stays green like the rest of the
timestamp value, matching the tool's actual output.

og.png was re-rendered at 1200x630 from an HTML template via headless
chromium, preserving the existing Tokyo Night layout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bsg62
bsg62 force-pushed the feat/relative-time-and-stdin-guard branch from 29446d4 to 65b5646 Compare July 25, 2026 19:05
@bsg62
bsg62 merged commit c4ac3c2 into main Jul 25, 2026
7 checks passed
@bsg62
bsg62 deleted the feat/relative-time-and-stdin-guard branch July 25, 2026 19:09
bsg62 added a commit that referenced this pull request Jul 25, 2026
These docs/superpowers/plans files were untracked local notes swept into
PR #20 by an errant `git add -A`; they are not part of the project and are
restored to their prior untracked state.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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