by kruzovic7
Free open-source extractor for AI coding assistant chat histories. Supports Claude Code, Cursor, Windsurf, Aider, Cline/Roo Code, and more.
Unlocks once the catalog security scan passes (runs nightly).
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.
# Add to your Claude Code skills
git clone https://github.com/kruzovic7/ai-data-extractorGuides for using ai agents skills like ai-data-extractor.
See how ai-data-extractor compares with popular alternatives.
Extract your own local chat history from AI coding assistants into a single, normalized JSONL format - for fine-tuning, personal analytics, or just backing up years of conversations before an app's local database gets cleared.
Auto-discovers and extracts complete conversation history, including:
| # | Tool | Storage | Search location |
|---|---|---|---|
| 1 | Claude Code | JSONL, one file per session | ~/.claude/projects/**/*.jsonl |
| 2 | Codex CLI | JSONL "rollout" files | ~/.codex/sessions/**/rollout-*.jsonl |
| 3 | Cursor | SQLite (state.vscdb) |
~/…/Cursor/User/{global,workspace}Storage |
| 4 | Windsurf | SQLite, undocumented schema (heuristic) | ~/…/Windsurf/User/{global,workspace}Storage |
| 5 | Trae | SQLite + JSONL, undocumented (heuristic) | ~/…/Trae |
| 6 | Continue | JSON, one file per session | ~/.continue/sessions/*.json |
| 7 | Gemini CLI | JSON, one file per chat | ~/.gemini/tmp/<hash>/chats/*.json |
| 8 | OpenCode | JSON (session/message/part trees) | ~/.local/share/opencode/storage/ |
| 9 | Cline / Roo Code (new) | JSON, one folder per task | <editor>/User/globalStorage/<ext-id>/tasks/ |
| 10 | Aider (new) | Markdown transcript per project | <project>/.aider.chat.history.md |
Every script searches macOS, Linux, and Windows conventions
(~/Library/Application Support, ~/.config, ~/.local/share, %APPDATA%,
%LOCALAPPDATA%) automatically - you don't need to tell it which OS you're on.
They're two of the most-used AI coding tools that the original list left out, and both have a genuinely different (and instructive) storage shape:
# No dependencies -- standard library only
python --version # 3.9+ required, 3.10+ recommended
# Interactive: pick which sources to extract from a numbered menu
python extract.py
# Or drive it directly
python extract.py --all
python extract.py --sources cursor,claude_code,aider
python extract.py --list # just show what's installed, don't extract
python extract.py --all --merge # also write all_conversations.jsonl
# Shorthand for "extract everything"
./extract_all.sh
python extract.py [--all] [--sources ids] [--list] [--output-dir DIR]
[--search-path PATH ...] [--merge]
--all Extract every supported source, no prompts.
--sources ids Comma-separated source ids (see table above for names,
or run with --list to see them). Skips the menu.
--list Report what was found for each source without
extracting anything -- a fast, safe preview.
--output-dir DIR Where to write JSONL (default: ./extracted_data)
--search-path PATH Extra directory to search, on top of the normal OS
locations. Repeatable. Mainly useful for:
- Aider, which has no fixed app-data folder and
needs to know where your projects live
- nonstandard install locations for anything else
--merge After extracting, also concatenate everything into
all_conversations.jsonl
Each extractor can also still be run standalone, same as the original
toolkit (python -m extractors.cursor from the project root, or
python extractors/cursor.py), which is handy while debugging one source.
Every run creates timestamped files under extracted_data/:
extracted_data/
├── claude_code_conversations_20260816_143022.jsonl
├── cursor_conversations_20260816_143022.jsonl
├── aider_conversations_20260816_143022.jsonl
├── cline_conversations_20260816_143022.jsonl
└── ... one file per source you extracted, plus all_conversations.jsonl if --merge
Each line is one JSON conversation:
{
"messages": [
{
"role": "user",
"content": "How do I fix this TypeScript error?",
"code_context": [
{"file": "/Users/you/project/src/index.ts", "code": "const x: string = 123;"}
],
"timestamp": "2026-01-16T14:30:22Z"
},
{
"role": "assistant",
"content": "The error occurs because you're assigning a number to a string type...",
"tool_use": [{"name": "edit_file", "input": {"path": "src/index.ts"}}],
"timestamp": "2026-01-16T14:30:25Z"
}
],
"source": "cursor-composer",
"session_id": "c1a2b3...",
"project_path": "/Users/you/project",
"name": "TypeScript Type Error Fix",
"created_at": 1705414222000
}
Fields vary a bit by source (not every tool records code_context, token
usage, or project_path) - messages, source, and session_id are the
only ones you can always rely on.
Application Support, .config, .local/share, %APPDATA%, etc).messages[] schema above.extracted_data/.Nothing here ever opens a database for writing, and every reader is wrapped so that one corrupt or locked file can't take down the whole run - you'll get a partial result and move on, not a stack trace.
None of these publish their storage schema, and it has changed multiple
times (Cursor alone has gone through at least three shapes: workspace
ItemTable chat, inline composer, and split bubbleId composer). The
cursor.py extractor implements all three known shapes explicitly.
windsurf.py and trae.py instead use a generic heuristic
(extractors/common.py::heuristic_extract_chat_from_kv) that scans
chat-related keys and walks the parsed JSON looking for objects shaped like
a role + text pair. It's honest best-effort, not a documented format - if
a future version changes shape and stops matching, that's expected; adjust
KEY_HINTS in the relevant file or send a PR.
Aider has no central session store - every project directory gets its own
.aider.chat.history.md. By default this toolkit scans your home directory
plus a handful of common project-root names (projects, code, dev,
repos, workspace, src, Documents) up to 5 directories deep, skipping
node_modules, .git, and similar. If your projects live somewhere else,
point at them directly:
python extract.py --sources aider --search-path ~/client-work --search-path /mnt/data/repos
Every extractor is a small module with the same two-function interface -
copy the simplest one (continue_ext.py is a good template) and fill in:
DISPLAY_NAME = "My Tool"
SOURCE_ID = "my_tool"
def find_installations(extra_paths: list[Path] | None = None) -> list[Path]:
"""Return the directories/files worth scanning."""
def extract(installations: list[Path]) -> list[dict]:
"""Return a list of conversation dicts matching the schema above."""
Then register it in extract.py's REGISTRY list. extractors/common.py
has the SQLite/JSON/JSONL readers and the two generic heuristics you'll
probably want.
This extracts data from tools running under your own user account. Before sharing or training on it:
pip install detect-secrets --break-system-packages
detect-secrets scan extracted_data/*.jsonl
code_context and tool_use fields are the most likely places to find them.extracted_data/ to a public repo (it's already in
.gitignore). Keep it on encrypted storage if it contains client or
proprietary work.from datasets import load_dataset
dataset = load_dataset("json", data_files="extracted_data/*.jsonl", split="train")
dataset = dataset.filter(lambda x: any(m["role"] == "assistant" for m in x["messages"]))
def format_chat(example):
return {"text": tokenizer.apply_chat_template(example["messages"], tokenize=False)}
dataset = dataset.map(format_chat)
"No installation found" - the tool either isn't installed, has no chat
history yet, or lives somewhere nonstandard. Pass --search-path to point
at it directly, or check extractors/<tool>.py's SEARCH_DIRS /
APP_DIR_NAMES constant and add your path there.
Cursor/Windsurf database locked - reads are opened
ai-data-extractor is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by kruzovic7. Free open-source extractor for AI coding assistant chat histories. Supports Claude Code, Cursor, Windsurf, Aider, Cline/Roo Code, and more. It has 78 GitHub stars.
ai-data-extractor's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/kruzovic7/ai-data-extractor" and add it to your Claude Code skills directory (see the Installation section above).
ai-data-extractor is primarily written in Python. It is open-source under kruzovic7 on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh ai-data-extractor against similar tools.
No comments yet. Be the first to share your thoughts!