| name | recap |
| description | Token-savvy session continuation. Rebuilds working context from transcript + soul memories in ~1500 tokens instead of replaying full history. Use when starting a new session to continue previous work. |
| aliases | ["context-resume","session-rebuild"] |
| execution | direct |
Recap: Token-Savvy Session Continuation
Reconstructs working context from a previous session's transcript and soul memories,
fitting the result into ~1500 tokens.
Step 0: Detect Environment
First, determine which tool you are running in:
ls ~/.codex/sessions/ 2>/dev/null && echo "CODEX" || echo "CLAUDE"
Then follow the appropriate path below.
Claude Code Path
Step 1 (Claude): Identify the session
ls -t ~/.claude/projects/-<encoded-cwd>/*.jsonl | head -5
Pick the second most recent (first = current session being written to).
Session_id = filename without .jsonl.
Step 2 (Claude): Extract key signals
Read user messages in two passes:
mcp__chitta__read_transcript({
session_id: "<id>",
role_filter: "user",
max_chars_per_turn: 150,
limit: 30
})
mcp__chitta__read_transcript({
session_id: "<id>",
role_filter: "user",
max_chars_per_turn: 150,
start_turn: -30,
limit: 30
})
Read last 15 assistant messages:
mcp__chitta__read_transcript({
session_id: "<id>",
role_filter: "assistant",
max_chars_per_turn: 200,
start_turn: -20,
limit: 15
})
Codex Path
Step 1 (Codex): Find recent sessions for current project
CWD=$(pwd)
python3 - <<'EOF'
import os, json, glob
cwd = os.getcwd()
sessions = []
for f in glob.glob(os.path.expanduser("~/.codex/sessions/**/*.jsonl"), recursive=True):
try:
first = json.loads(open(f).readline())
if first.get("payload", {}).get("cwd") == cwd:
sessions.append((os.path.getmtime(f), f))
except: pass
for mtime, path in sorted(sessions, reverse=True)[:5]:
sid = os.path.basename(path).replace(".jsonl", "").split("-", 3)[-1]
size = os.path.getsize(path)
print(f"{path} [{sid}] {size//1024}KB")
EOF
Pick the most recent (the current session has no prior turns worth recapping).
Session path = the full file path. Session_id = the UUID suffix after the timestamp.
Step 2 (Codex): Extract key signals from transcript
Use python3 to parse the Codex JSONL format (different from Claude's format):
python3 - <<'EOF'
import json, sys
TRANSCRIPT = "/path/to/rollout-....jsonl"
MAX_CHARS = 150
LIMIT = 40
ROLE_FILTER = "user"
turns = []
for line in open(TRANSCRIPT):
d = json.loads(line)
if d.get("type") == "response_item":
p = d["payload"]
role = p.get("role", "")
if ROLE_FILTER and role != ROLE_FILTER:
continue
content = p.get("content", "")
if isinstance(content, list):
content = " ".join(b.get("text","") for b in content if isinstance(b,dict) and b.get("type")=="text")
content = str(content).strip()
if content:
turns.append((role, content[:MAX_CHARS]))
for role, text in turns[:20]:
print(f"[{role}] {text}")
print("--- tail ---")
for role, text in turns[-20:]:
print(f"[{role}] {text}")
EOF
Run twice: once for user messages (ROLE_FILTER="user"), once for assistant (ROLE_FILTER="assistant").
When reading user messages, IGNORE these noise patterns:
<local-command-*> blocks (model switches, login, plugin commands)
<command-name> blocks (slash commands)
<task-notification> blocks (agent completions)
<system-reminder> blocks (hook output)
[Request interrupted by user]
- Repeated identical messages
Focus ONLY on lines that express intent: questions, requests, corrections, confirmations.
Step 3: Get soul context
Query soul for memories relevant to what was being worked on:
mcp__chitta__smart_context({
task: "<summarize what user was working on from step 2>",
mode: "fast",
limit: 300
})
Step 4: Get current environment state
git status --short
git log --oneline -5
Step 5: Synthesize the recap block
Combine everything into a structured block under 1500 tokens:
## Session Recap: <session_id>
### What was being done
<2-3 sentences from user messages — the primary task and subtasks>
### Key decisions made
<Bullet list of important choices/fixes from assistant messages>
### Current state
- **Branch**: <branch>
- **Uncommitted**: <files or "clean">
### Pending work
<What was left unfinished — derived from last user messages + soul context>
### Key context
<Critical facts that would be lost without replay — error patterns,
architectural decisions, corrections the user made>
Rules
- Never replay full tool outputs — those are the token killers
- User corrections are highest priority — always include them
- Skip system-reminder content — it's noise for resume purposes
- Skip task-notification content — ephemeral
- Decisions > descriptions — "chose X because Y" not "I looked at file Z"
- Include file paths only if they're actively being edited
Token Budget
| Section | Target |
|---|
| What was being done | 200 tokens |
| Key decisions | 400 tokens |
| Current state | 150 tokens |
| Pending work | 300 tokens |
| Key context | 450 tokens |
| Total | ~1500 tokens |
When to use /recap vs /compact
| Situation | Action | Why |
|---|
| Same session, context growing | /compact | Preserves conversation, trims tool output |
| New session, continue previous work | /recap | ~1500 tokens vs replaying full history |
| Session idle >5 min (cache expired) | New session + /recap | Avoids cache-write repricing of stale context |
| >20 subagents spawned | /compact or new + /recap | Each subagent cold-starts a cache |
| Transcript >20MB | New session + /recap | Reduces cache-write volume |
Cost perspective: A 50MB session that resumes after cache expiry re-prices all context
at cache-write rates (~$18.75/MTok). Starting fresh with /recap costs ~$0.03.
Arguments
- No args: resume from most recent previous session for current project (auto-detect)
<session_id>: resume from specific session
last N: show last N sessions to pick from