Find an Older Thread
Search every local transcript store at once — T3 Code, Codex, and Claude Code — and return the thread the user is thinking of, with the command that resumes it.
The usual next step is t3ex-fork-thread, which continues a T3 Code thread
under a different model. This skill is how you get the id to hand it.
Run the search
find_thread.py sits next to this file:
python3 find_thread.py "<pattern>"
Python 3.10+ and ripgrep. The pattern is a case-insensitive regex, so
indicator|spinner works.
| Flag | Effect |
|---|---|
--source t3code|codex|claude |
Limit to one store, repeatable |
--repo TEXT |
Only threads whose working directory contains TEXT |
--since N |
Only threads active in the last N days |
--limit N |
Results to show (default 10) |
--scan-limit N |
Transcript files to open per store, newest first (default 40) |
--include-deleted |
Include T3 threads deleted in the UI |
--paths |
Print the backing file for each hit |
--json |
Machine-readable output |
Results are newest first — when someone asks for "that older thread", they almost always mean the most recent one that matches.
Reading the output
3. [t3code] Start Localhost Dev Server
when 2026-07-25 08:33 · 16 matches · codex/gpt-5.6-sol
repo /Users/madda/dev/active/Maestro3
said This site can't be reached localhost:3001: Connection refused…
also as codex 019f97a1-e620-7a92-abc6-047811367bfb
resume /t3ex-fork-thread ce419dc7-4b8f-4d7c-b438-cdeed11ba120
also as means the same conversation exists in a second store. A T3 Code thread
run on Codex writes a rollout file too; the script folds them into one result and
reports the T3 Code id, because that is the one t3ex-fork-thread takes.
Narrowing
A bare word matches far more than you expect. Every session's system prompt
carries the full list of installed skills, so a term like beads or chrome
hits thousands of transcripts that never discussed it.
Start narrow and widen only if nothing lands:
- An exact phrase the user remembers, or a distinctive identifier — an error string, a file name, a port number.
- Add
--repowhen they name a project. This is the single most effective filter. - Add
--sincewhen they say "yesterday" or "last week". - Only then loosen to
term1|term2.
If the script reports transcripts went unread, it means the pattern was too
broad — narrow it rather than raising --scan-limit, which just reads more
irrelevant files.
Confirm before answering
Match counts include assistant replies and tool output, not just what the user typed, so a high count is not proof the thread is about the topic. Before naming a winner, look at the actual text:
python3 find_thread.py "<pattern>" --paths --limit 3
rg -n -i "<pattern>" "<the file path>" | head -20
Quote the line that proves the match. If two threads are close, name the best one and mention the runner-up in a sentence — do not make the user guess.
If nothing matches, say which stores were searched and what pattern was used. Do not silently widen to a vaguer term and present those results as the answer.
Where the transcripts live
| Store | Location | Id |
|---|---|---|
| T3 Code | ~/.t3/userdata/state.sqlite |
thread UUID |
| Codex | ~/.codex/sessions/YYYY/MM/DD/rollout-<ts>-<uuid>.jsonl |
trailing UUID |
| Codex archive | ~/.codex/archived_sessions/ |
trailing UUID |
| Claude Code | ~/.claude/projects/<path-slug>/<uuid>.jsonl |
filename |
~/.codex-profiles/*/sessions and ~/.claude-profiles/*/projects are searched
too, but on this machine they are nearly empty — the real history is under
~/.codex and ~/.claude. Claude project folders encode the repo path with
dashes: /Users/madda/dev/active/Maestro3 becomes
-Users-madda-dev-active-Maestro3.
Escape hatch — record shapes
For anything the script does not surface, read the transcripts directly.
Codex rollouts. First line is session_meta, carrying session_id, cwd,
and originator — t3code_desktop means the session was driven by T3 Code
rather than the CLI. Conversation lines are response_item with
payload.role and payload.content[].text.
Claude transcripts. ai-title holds a generated title, last-prompt the
most recent prompt, and user/assistant the conversation. user records also
carry cwd, sessionId, gitBranch, and timestamp.
T3 Code. See the schema table in t3ex-fork-thread.
Three traps:
- The first user message is never the real prompt. Both harnesses inject
# AGENTS.md instructions,<recommended_plugins>,<environment_context>and similar ahead of it. Skip those wrappers. - Claude subagent turns are inline. Filter
isSidechain: trueout or a subagent's prompt reads as the user's. ~/.codex/sessions/index/catalog.jsonlis partial — about 123 of 4,900 rollouts. Useful for metadata, useless as a search index.
Related
t3ex-fork-thread continues a T3 Code thread once you have its id.