Skip to content

Instantly share code, notes, and snippets.

@awhitty
Created March 2, 2026 20:56
Show Gist options
  • Select an option

  • Save awhitty/832d4a1b71f9b5bbc93c68f77e9c319a to your computer and use it in GitHub Desktop.

Select an option

Save awhitty/832d4a1b71f9b5bbc93c68f77e9c319a to your computer and use it in GitHub Desktop.
recall — Cross-session context for Claude Code

recall — Cross-session context for Claude Code

A skill that lets Claude Code load context from past conversations so you can pick up where you left off. Say /recall the discussion about X and get a structured brief of what happened, what was decided, and where it stopped.

Claude Code works best in short, intense bursts — but that means you're constantly /clearing context. Recall bridges those gaps.

How it works

  1. You say /recall <topic or session ID>
  2. Claude searches your conversation history using DuckDB (fast, even across hundreds of sessions)
  3. You get a synthesized Context Brief — not a raw dump, but a structured summary focused on where it left off

Prerequisites

Install

# 1. Put the search script on your PATH
cp recall-search ~/.local/bin/
chmod +x ~/.local/bin/recall-search

# 2. Install the skill into your project
mkdir -p /path/to/your/project/.claude/skills/recall
cp SKILL.md /path/to/your/project/.claude/skills/recall/SKILL.md

Repeat step 2 for each project where you want recall available. The search script only needs to be installed once.

Make sure ~/.local/bin is on your PATH. If it isn't:

echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc  # or ~/.zshrc

Usage

Inside Claude Code:

/recall the actor model discussion
/recall my most recent session
/recall 471982bc
/recall that script we built for zombie processes

You can also use the search script directly from your terminal:

recall-search sessions              # list recent sessions
recall-search search actor model    # keyword search
recall-search spine 471982bc        # full conversation text
recall-search context 471982bc      # compact: first 10 + last 20 messages
recall-search topics                # topic overview of all sessions
recall-search stats                 # usage dashboard
recall-search impact                # most engaged sessions

How conversation history is stored

Claude Code saves conversations as JSONL files at:

~/.claude/projects/{project-slug}/*.jsonl

The project slug is your working directory with / replaced by -. For example:

  • /home/user/projects/myapp becomes -home-user-projects-myapp

Each file is one session. The search script reads these directly with DuckDB — no indexing step, no server, no setup beyond having DuckDB installed.

Environment variables

Variable Default Description
CLAUDE_PROJECT_DIR $(pwd) Override project directory for history lookup
RECALL_LIMIT 20 Max results for search/sessions commands
name description
recall
Load context from a past conversation into this fresh session so you can resume work. Not a search tool — a context handoff mechanism across /clear boundaries.

You are loading context from a past conversation so the user can continue where they left off. This is the most common thing you'll do — the user works in fast, intense bursts, clearing context constantly, and /recall bridges those gaps.

What You're Given

The user's query will be one of:

  1. A topic — "we were chatting about the actor model", "the discussion about modularizing the prompt"
  2. A session ID fragment — "471982bc...", a UUID or prefix of one
  3. A vague description — "that script we built for zombie processes", "the s3-send thing"
  4. A recency reference — "the last conversation", "my most recent session"
  5. A request to review — "read the agent output from my most recent convo", "why did this session run out of context?"

Where Conversations Live

Conversation history is stored as JSONL files at:

~/.claude/projects/{project-dir}/*.jsonl

The {project-dir} is the working directory path with / replaced by - and a leading -. For example:

  • /home/user/projects/myapp-home-user-projects-myapp

Each .jsonl file is one conversation session. The filename (minus .jsonl) is the session UUID.

JSONL Record Structure

Each line is a JSON object. The important fields:

  • type: "user", "assistant", "progress", "file-history-snapshot"
  • message.role: "user" or "assistant"
  • message.content: string (user messages) or array of content blocks (assistant messages — look for type: "text" blocks)
  • timestamp: ISO 8601
  • sessionId: UUID of the session
  • gitBranch: branch at time of message
  • cwd: working directory

Only type: "user" and type: "assistant" records with text content matter. Skip progress, file-history-snapshot, tool use blocks, and thinking blocks.

Tools

A DuckDB-powered search script called recall-search should be on your PATH (installed to ~/.local/bin/ or similar). It searches all conversation JSONL files in seconds. Always use this script first — it replaces manual grep/jq parsing.

# Search for sessions mentioning keywords (ranked by hit count)
recall-search search <keyword1> <keyword2> ...

# List all sessions (most recent first)
recall-search sessions

# Extract conversation spine (all user + assistant text messages)
recall-search spine <session-id-prefix>

# Compact context: first 10 + last 20 messages (for long sessions)
recall-search context <session-id-prefix>

Process

Phase 1: Find the Conversation

If session ID fragment: Run recall-search spine <prefix> directly.

If "last" / "most recent": Run recall-search sessions and take the most recent (excluding the current session).

If topic or vague description: Extract 2-4 keywords and run recall-search search <keywords>. Results are ranked by hit count with session ID, date, branch, and first user message.

If there's a single strong match, skip the selection step and load it directly. If no matches in the current project, fall back to grep across ~/.claude/projects/.

Phase 2: Load and Extract

Use recall-search spine <session-id> to get the full conversation spine (user + assistant text only, no tool calls or thinking blocks).

For very long conversations (>100 messages in output), use recall-search context <session-id> instead — it returns the first 10 + last 20 messages, which captures the topic setup and where things left off.

For targeted extraction within a loaded spine, search for key decision language ("let's go with", "decided", "the plan is", "changed to").

Phase 3: Synthesize the Context Brief

Do not dump the raw conversation. Synthesize a structured brief designed for continuation:

## Context Brief: [topic in 5-10 words]

**Session:** [id fragment] | [date] | branch: [branch]
**Duration:** [first timestamp] → [last timestamp] ([N] user messages)

### What We Were Doing
[1-3 sentences: the goal, the approach, the scope]

### Key Decisions
- [decision 1 — what was chosen and why]
- [decision 2]
[only include if decisions were actually made]

### Where It Left Off
[what was the last thing discussed, what was the next step,
 what was unresolved — this is the most important section]

### Files Touched
[list files that were read, edited, or created — extract from tool calls if visible]

### Open Threads
[questions raised but not answered, deferred items, things to revisit]

Adjust the format to fit the conversation. Short sessions might only need "What We Were Doing" and "Where It Left Off". Review/audit requests might need more emphasis on "Key Decisions" and critique. Drop any section that has nothing useful to say.

Phase 4: Present and Stand By

After presenting the brief, stop and wait. The user will tell you what to do next — resume the work, dig deeper into a specific thread, or load a different conversation. Don't proactively start working on whatever the past conversation was about.

Principles

  • Speed over completeness. The user is trying to get back to work. A good-enough brief in 15 seconds beats a perfect one in 60.
  • The "where it left off" section is the whole point. Everything else is scaffolding for that. If you can only produce one section, make it that one.
  • Don't editorialize. Report what happened, not what you think about it — unless the user specifically asks for review/critique.
  • Conversations are private context. Don't be surprised by informal language, false starts, or abandoned approaches. That's normal working context.
  • When in doubt, show options. If multiple conversations could match, list them rather than guessing wrong.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment