Transcript query
Claude Code skills for marketing, content, and decision-making. Install with: npx skills add derivativelabs/skills
npx -y skills add DerivativeLabs/skills --skill transcript-queryAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Query AI coding session transcripts across Claude, Codex, Cursor, and Gemini. Use when: transcript, session history, previous work
SKILL.md
10.5 KB, ~2.5k tokens by cl100k_base, as published. Nobody here has run it
Transcript Query
Purpose
Query and analyze AI coding session transcripts across multiple CLIs (Claude Code, Codex, Cursor, Gemini CLI) to review work, decisions, and context in any repo.
Use Cases
- Contextual Memory: "What were we working on before X?"
- Decision Tracking: "Why did we choose approach Y?"
- Issue History: "What errors did we encounter with Z?"
- File History: "When did we modify file X?"
- Timeline Reconstruction: "Show me all work on feature Y"
How It Works
Claude Code stores session transcripts as JSONL files in ~/.claude/projects/<project-path>/<session-id>.jsonl.
This skill:
- Parses transcript JSONL files
- Extracts structured data (messages, tool uses, files, errors)
- Searches by keyword, date, topic
- Reconstructs context and timeline
Usage
Answer "What were we working on before X?"
import { TranscriptParser } from './lib/transcript-parser.js';
const parser = new TranscriptParser();
const result = await parser.findWorkBefore(
process.cwd(), // Current project path
'memory sync daemon' // Topic to find
);
if (result.found) {
console.log('Previous work:');
result.previousSessions.forEach(s => {
console.log(`\n## ${new Date(s.startTime).toISOString()}`);
console.log(`Branch: ${s.gitBranch}`);
console.log(`Key topics: ${s.keyTopics.join(', ')}`);
console.log(`Summary: ${s.summary.messageCount} messages, ${s.summary.filesModifiedCount} files changed`);
});
}
Search for specific topic
const transcripts = await parser.listTranscripts(process.cwd());
for (const transcript of transcripts) {
const data = await parser.parseTranscript(transcript.path);
const matches = parser.searchMessages(data, 'authentication');
if (matches.length > 0) {
console.log(`Found in ${transcript.sessionId}:`);
matches.forEach(m => {
console.log(` [${m.type}] ${m.content.substring(0, 100)}...`);
});
}
}
Get session summary
const recent = await parser.getMostRecentTranscript(process.cwd());
const data = await parser.parseTranscript(recent.path);
console.log('Most recent session:');
console.log(` Duration: ${data.summary.durationFormatted}`);
console.log(` Messages: ${data.summary.messageCount}`);
console.log(` Files modified: ${data.summary.filesModifiedCount}`);
console.log(` Errors: ${data.summary.errorCount}`);
Find context around a message
const data = await parser.parseTranscript(transcriptPath);
const context = parser.findContextBefore(
data,
'lets merge', // Target message
5 // Number of context messages
);
if (context) {
console.log('Context before "lets merge":');
context.contextMessages.forEach(m => {
console.log(`[${m.type}] ${m.content}`);
});
}
Integration with Claude
When Claude needs to answer questions about previous work, it can:
- Check current project path from
process.cwd() - List available transcripts for the project
- Search for relevant sessions by keyword/topic
- Extract context from previous sessions
- Present findings to user
Example: Autonomous usage
// When user asks: "what were we working on before the daemon?"
async function answerContextQuestion(question) {
const parser = new TranscriptParser();
// Extract key terms from question
const searchTerm = extractKeyTerm(question); // e.g., "daemon"
// Find relevant work
const result = await parser.findWorkBefore(process.cwd(), searchTerm);
if (result.found) {
// Construct answer from previous sessions
return `Before working on ${searchTerm}, we were working on:\n\n` +
result.previousSessions.map(s =>
`- ${new Date(s.startTime).toLocaleDateString()}: ${s.keyTopics.slice(0, 3).join(', ')} ` +
`(${s.summary.filesModifiedCount} files changed)`
).join('\n');
} else {
return `No previous sessions found before ${searchTerm}.`;
}
}
Integration Points
1. Session Start Hook
Load recent context automatically:
// .claude/hooks/session_start_with_transcript.mjs
import { TranscriptParser } from './skills/transcript-query/lib/transcript-parser.js';
const parser = new TranscriptParser();
const recent = await parser.getMostRecentTranscript(process.cwd());
if (recent) {
const data = await parser.parseTranscript(recent.path);
console.log(`Last session: ${data.summary.durationFormatted} ago`);
console.log(`Topics: ${parser.extractKeyTopics(data).slice(0, 3).join(', ')}`);
}
2. Memory Sync Daemon
Background indexing of transcripts:
// Watch for new transcripts
const watcher = fs.watch(parser.projectsDir, { recursive: true });
for await (const event of watcher) {
if (event.filename.endsWith('.jsonl')) {
// Index new transcript
const data = await parser.parseTranscript(event.filename);
// Store in searchable index (your vector store of choice)
await indexTranscript(data);
}
}
3. Command Interface
Add CLI commands:
# Query transcripts
node transcript-query.mjs search "authentication"
node transcript-query.mjs before "daemon"
node transcript-query.mjs recent
node transcript-query.mjs summary <session-id>
Data Structure
Parsed transcript structure:
{
sessionId: "uuid",
startTime: "2026-02-05T14:52:26.457Z",
endTime: "2026-02-05T18:30:15.123Z",
cwd: "/path/to/project",
gitBranch: "feat/branch-name",
messages: [
{
type: "user" | "assistant",
content: "message text",
timestamp: "ISO 8601",
uuid: "message-uuid"
}
],
toolUses: [
{
tool: "Read" | "Edit" | "Write" | ...,
parameters: {},
timestamp: "ISO 8601"
}
],
filesModified: [
{
path: "relative/path/to/file",
action: "Edit" | "Write",
timestamp: "ISO 8601"
}
],
errors: [
{
message: "error description",
timestamp: "ISO 8601"
}
],
summary: {
messageCount: 42,
userMessageCount: 15,
toolUseCount: 87,
filesModifiedCount: 12,
errorCount: 2,
durationMs: 13789000,
durationFormatted: "3h 49m 49s"
}
}
Performance Considerations
- Lazy loading: Only parse transcripts when needed
- Caching: Cache parsed transcripts in memory
- Indexing: For large projects, maintain a searchable index
- Async: All file operations are async
Future Enhancements
- Vector embeddings: Use vector search for semantic queries
- Automatic summarization: Use an LLM API to summarize sessions
- Trend analysis: Track patterns over time
- Skill extraction: Automatically identify reusable patterns
- Decision graph: Build graph of decisions and their outcomes
Security & Privacy
- Transcripts contain full conversation history
- May include sensitive data (credentials, keys, personal info)
- Keep transcripts local or encrypt before cloud storage
- This skill only reads, never modifies transcripts
Dependencies
- Node.js >= 18 (for fs/promises)
- Claude Code (generates .jsonl transcripts)
Testing
# Run parser tests
node test-transcript-parser.mjs
# Test with current project
node -e "
import { TranscriptParser } from './lib/transcript-parser.js';
const parser = new TranscriptParser();
const transcripts = await parser.listTranscripts(process.cwd());
console.log(\`Found \${transcripts.length} transcripts\`);
"
Unified Cross-CLI Query
The unified-transcript-query.mjs tool discovers and searches transcripts across all 4 CLIs for any project.
Supported CLIs
| CLI | Format | Location | Discovery |
|---|---|---|---|
| Claude Code | JSONL | ~/.claude/projects/<normalized-path>/ | Path normalization (/ and _ → -) |
| Codex | JSONL | ~/.codex/sessions/YYYY/MM/DD/ | Scan all, filter by cwd |
| Cursor | Plain text | ~/.cursor/projects/*/agent-transcripts/ | Match by project directory name |
| Gemini CLI | JSON | ~/.gemini/tmp/<sha256>/chats/ | SHA-256 hash of absolute project path |
Unified Commands
# List all sessions grouped by CLI
node unified-transcript-query.mjs list [project]
# Chronological timeline across all CLIs
node unified-transcript-query.mjs timeline [project] --since 2026-02-01
# Search across all CLIs with fuzzy matching
node unified-transcript-query.mjs search "authentication" [project]
# Aggregate stats per CLI
node unified-transcript-query.mjs summary [project]
# Show specific session details
node unified-transcript-query.mjs session <id> --cli gemini
Options
--since YYYY-MM-DD— Filter sessions after date--until YYYY-MM-DD— Filter sessions before date--cli name— Filter by specific CLI (claude|codex|cursor|gemini)--limit N— Limit number of results--all— Search all sessions (no limit)
Programmatic API
import { UnifiedTranscriptParser } from './lib/unified-parser.js';
const parser = new UnifiedTranscriptParser();
// Discover all sessions across CLIs
const sessions = await parser.discoverAll('/path/to/project');
// Get chronological timeline
const timeline = await parser.getTimeline('/path/to/project', { since: '2026-02-01' });
// Search across all CLIs
const results = await parser.searchAll('/path/to/project', 'deploy');
// Get summary stats
const summary = await parser.getSummary('/path/to/project');
Architecture
unified-transcript-query.mjs (CLI entry point)
│
UnifiedTranscriptParser (orchestrator)
│
┌────┼────────┬───────────┐
▼ ▼ ▼ ▼
Claude Codex Cursor Gemini
Adapter Adapter Adapter Adapter
(JSONL) (JSONL) (txt) (JSON)
All adapters normalize to the same data model, with cli field added to identify the source.
Backward Compatibility
The original transcript-query.mjs continues to work for Claude-only queries. The unified tool is a separate entry point that wraps all adapters.
References
- Claude Code transcript format:
.claude/projects/<project>/<session>.jsonl - Codex transcript format:
.codex/sessions/YYYY/MM/DD/rollout-*.jsonl - Cursor transcript format:
.cursor/projects/*/agent-transcripts/*.txt - Gemini CLI transcript format:
.gemini/tmp/<sha256>/chats/session-*.json - JSONL spec: https://jsonlines.org/
- Session hooks:
.claude/hooks/directory
What ships with it: 6 files
47.6 KB alongside SKILL.md, 6 of them executable
lib/
- adapters/claude-adapter.jsruns5.6 KB
- adapters/codex-adapter.jsruns7.9 KB
- adapters/cursor-adapter.jsruns6.7 KB
- adapters/gemini-adapter.jsruns6.2 KB
- transcript-parser.jsruns15.2 KB
- unified-parser.jsruns6.0 KB