skills/finding-old-chats/SKILL.md
Use when the user asks to review, find, summarize, or check Claude Code chat transcripts from a past date or time range ("review my chats from May 1st", "what was I working on yesterday", "any unfinished sessions this week"). Reads transcripts under `~/.claude/projects/`, handles local-time vs UTC correctly so late-evening sessions don't get dropped, and flags chats whose last assistant turn looks like an unanswered question.
npx skillsauth add AMindToThink/claude-code-settings finding-old-chatsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Claude Code stores every session as a JSONL file under ~/.claude/projects/<dashed-cwd>/<uuid>.jsonl. When the user asks for "chats from <date>", they mean their wall-clock day, not UTC — and the timestamps inside the JSONL are UTC. A naive timestamp.startswith("YYYY-MM-DD") filter silently drops sessions the user clearly considers part of that day.
This skill bundles a script (scan_chats.py) that does it right: convert local day → UTC window, then test each chat by interval-overlap, not substring match.
Real failure on 2026-05-07: user asked to review May 1 chats. The agent filtered with startswith("2026-05-01"), missed two sessions whose first timestamp was 2026-05-02T00:32Z and 2026-05-02T00:43Z — both are May 1 evening in Central US time, but every timestamp inside them starts with 2026-05-02.
The mirror trap: a session whose first timestamp is 2026-05-01T03:55Z is April 30 evening local, not a May 1 chat — but it would match the naive UTC filter.
Either way: do not use UTC-substring filtering. Use the script.
~/.claude/projects/<dashed-cwd>/<session-uuid>.jsonl
Directory name is the absolute working-directory path with / → -, leading dash. Example:
/home/cs29824/matthew/icl-diversity~/.claude/projects/-home-cs29824-matthew-icl-diversity/Each JSONL line is {"type": "user"|"assistant"|"summary"|..., "timestamp": "2026-05-01T04:25:36.489Z", "message": {...}}. Inside message.content, content can be a string or a list of {type: text|tool_use|tool_result, ...} parts.
# Default: use system timezone
~/.claude/skills/finding-old-chats/scan_chats.py --date 2026-05-01
# System TZ is UTC but you think in local time — pass an IANA name
~/.claude/skills/finding-old-chats/scan_chats.py --date 2026-05-01 --tz America/Chicago
# Don't know the user's TZ — pad the window
~/.claude/skills/finding-old-chats/scan_chats.py --date 2026-05-01 --buffer-hours 12
# Different project
~/.claude/skills/finding-old-chats/scan_chats.py --date 2026-05-01 --project /path/to/project
# Show first user message + tail of each chat
~/.claude/skills/finding-old-chats/scan_chats.py --date 2026-05-01 --tz America/Chicago --full-msgs
# Just the chats whose last assistant turn looks like an unanswered question
~/.claude/skills/finding-old-chats/scan_chats.py --date 2026-05-01 --tz America/Chicago --unfinished-only
The script prints the UTC window it actually scans, so the caller can sanity-check the timezone.
digraph tz_decision {
"User says \"chats from <date>\"" [shape=box];
"Do you know user's IANA TZ?" [shape=diamond];
"Pass --tz <name>" [shape=box];
"Is system TZ UTC?" [shape=diamond];
"Default (system tz)" [shape=box];
"Pass --buffer-hours 12" [shape=box];
"User says \"chats from <date>\"" -> "Do you know user's IANA TZ?";
"Do you know user's IANA TZ?" -> "Pass --tz <name>" [label="yes"];
"Do you know user's IANA TZ?" -> "Is system TZ UTC?" [label="no"];
"Is system TZ UTC?" -> "Pass --buffer-hours 12" [label="yes"];
"Is system TZ UTC?" -> "Default (system tz)" [label="no"];
}
--buffer-hours 12 casts a wider net (36-hour UTC window for one local day) and accepts some over-reporting in exchange for never missing a chat. Skim the printed UTC bounds and ignore obvious outliers.
A chat is heuristically "probably unfinished" when:
assistant message ends with ? in its final 500 chars or ends with ] (cut off mid-tool_use), AND[tool_result...] echo, a <system-reminder>, a <command-name> slash-command marker, a <bash-input>/<bash-stdout> echo, or a <local-command-caveat> echo.scan_chats.py --unfinished-only flags these. Expect false positives:
? is hundreds of chars before genuine resolutionAlways read the actual last messages before reporting "unfinished" to the user. The flag is a triage shortcut, not a verdict.
timestamp.startswith("YYYY-MM-DD") — misses sessions that started after local-midnight-but-before-UTC-midnight.find -newermt on the JSONL files — uses file mtime, which moves whenever the IDE re-opens or re-writes them. Use timestamps inside the file.is_real_user_msg filtering.Read tool — single-shot read can be near the file-size limit and is wasteful. The script streams line-by-line.See scan_chats.py in this directory. ~200 lines, stdlib only (zoneinfo from Python 3.9+).
development
Use when the user asks to check, audit, or improve a website or web project for accessibility (a11y), WCAG compliance, screen reader support, keyboard navigation, color contrast, or alt text. Triggers a plan-mode investigation against the TeachAccess design and code checklists, then implements approved fixes.
development
--- name: make-anonymous-branch description: Use when preparing a research repo for double-blind submission via anonymous.4open.science (ICML/NeurIPS/ICLR/workshop). Builds a single `anon-submission` branch with code+data+paper, scrubs identity leaks (author names, home paths, emails, wandb metadata, PDF author fields), patches LaTeX for pdf.js compatibility, and leaves `main` untouched. Triggers: "make an anonymous branch", "anonymize my repo for X submission", "set up anonymous.4open.science",
development
Translate math (formulas, estimators, algorithms) into code so the implementation faithfully matches what the source actually specifies. Use when writing code from a formula, reviewing an LLM-generated implementation of a formula, debugging a numerical mismatch with a paper, designing a new metric/estimator, or refactoring an existing math-heavy computation. Especially load-bearing whenever aggregation operators (sums, means, expectations, products, geometric means) appear over indices that can be reordered, or whenever the same English label can refer to multiple non-equivalent estimators (e.g. ratio-of-means vs mean-of-ratios, micro-average vs macro-average, sample-weighted vs unweighted). Prevents the failure mode where a code path silently implements the wrong estimator under the same name as the intended one.
documentation
Consolidate scattered research notes, logs, experiment outputs, and submodule docs into a single living research paper. Use when the user wants to pull together multiple source documents into one structured paper.