Skip to content

feat: add td history command for issue timeline view - #66

Merged
marcus merged 4 commits into
mainfrom
historical-context
Oct 15, 2026
Merged

marcus merged 4 commits into
mainfrom
historical-context

Conversation

@marcus

@marcus marcus commented Mar 21, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds td history <issue-id> (alias td timeline): one chronological timeline of an issue's life, assembled from action_log, logs, handoffs, comments, git snapshots, and linked files.

  • Readable status history. Each lifecycle command writes an action row and its own narration log. The log is folded under its status change, so an approval's reason or a rejection's cause appears once, under Approved and closed or Rejected. Pairing is keyed on which commands narrate and with which log types. An agent's own --blocker or --decision note logged next to an update or delete stays a standalone, typed log.
  • Real field changes, e.g. Updated priority: P2 → P1, labels. Updates that only touch updated_at are skipped, and clearing an omitempty field shows as a change.
  • Review records, close-after-review, delete, and restore. A created event is synthesized when no create action exists.
  • Identical consecutive events collapse into one row with a count. One real issue had 135 identical dispatch-error comments.
  • Text output shows absolute local times with type labels and indented details. --json emits all timestamps in UTC; action rows are stored in UTC while logs carry a local offset, which had put dates on the wrong day. Errors use the standard JSON error envelope. --limit N keeps the most recent N rows.

Fixes to existing readers found along the way

  • Handoffs written Dec 2025–Feb 2026 stored their lists base64-encoded. td show silently dropped them (938 rows in td's own DB), and they decode now.
  • A log row left with a NULL id by the text-ID migration broke GetLogs for its issue.

Testing

  • Unit tests for ordering and UTC, narration folding (including the agent-chaining false-pair cases), update diffs, cleared fields, undone actions, comments and repeats, legacy handoffs, NULL log ids, and limit with collapsing. Command tests cover the printer, the JSON payload (including deleted_at), and error envelopes.
  • Ran td history --json against all 2,336 issues in td's own project DB: all render.
  • Full go test ./... and golangci-lint pass.
  • Two rounds of independent review by a sub-agent. Round 1 found the handoff failure, log mis-pairing, and dropped cleared fields; round 2 verified the fixes against the real DB and found no regressions.

🤖 Generated with Claude Code

marcus and others added 2 commits October 15, 2026 16:01
Adds a unified chronological timeline showing all events for an issue:
logs, handoffs, comments, git snapshots, and status changes from the
action_log. Supports --json and --limit flags.

Nightshift-Task: historical-context
Nightshift-Ref: https://github.com/marcus/nightshift

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rework of the nightshift timeline before merge:

- Fold the log a lifecycle command writes into its status-change event
  (same session, closest within -2s..+10s), so approvals show their
  reason once instead of as a duplicate line. Only transitions and
  reviews pair; a note logged right after td update stays a log.
- Report all timestamps in UTC in JSON and local time in text. Action
  rows are UTC and logs carry a local offset, so dates were shown on
  the wrong day.
- Show real field changes (priority: P2 -> P1), ignore updated_at-only
  updates, and sort changed fields deterministically.
- Read linked files from issue_files; the action_log rows are keyed by
  link ID, so file events never matched before.
- Cover review records, close-after-review, delete, and restore, and
  synthesize a created event when no create action exists.
- Collapse identical consecutive events into one with a count.
- Show short comments inline and long ones once, without cutting runes.
- Reuse GetHandoffs and GetLinkedFiles, check rows.Err, fix errcheck.
- Use absolute times with type labels, indent every detail line, and
  report errors through reportFailure so --json gets an error envelope.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@marcus
marcus force-pushed the historical-context branch from 2dd4dce to 2e68351 Compare October 15, 2026 23:07
marcus and others added 2 commits October 15, 2026 16:27
- Decode the base64-encoded handoff lists written Dec 2025-Feb 2026 in
  every handoff reader. td history failed on ~32% of issues in a real
  DB, and td show silently dropped those handoffs.
- Pair narration logs by action type and log type: only commands that
  always write their own log take one, and only of the types they write.
  A blocker logged after a status update or a decision logged before a
  delete stays a standalone, typed log. Window tightened to -0.5s..+5s.
- Diff the union of previous/new keys so clearing an omitempty field
  (sprint, labels, description) is shown instead of dropped.
- Trim a leading "Rejected: " from narration details, give the
  synthesized created event the creator session, drop the unreachable
  review_delete mapping, flag deleted issues (header and deleted_at),
  and reject a negative --limit.
- Tests for each, plus JSON envelope and error-path command tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A log row left with a NULL id by the Jan 2026 text-ID migration made
GetLogs fail for its issue; td history errored and td show silently
dropped every log. COALESCE the id. Also clarify the narration-pairing
and ASCII-slicing comments from review round 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@marcus
marcus merged commit 8c6cc6b into main Oct 15, 2026
4 checks passed
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