Lerim uses platform adapters to discover, normalize, and export agent sessions from different coding agent platforms into a unified JSONL format.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/lerim-dev/lerim-cli/llms.txt
Use this file to discover all available pages before exploring further.
Adapter protocol
All adapters conform to theAdapter protocol defined in src/lerim/adapters/base.py:
The protocol uses structural typing (
Protocol), so adapters don’t need to inherit from a base class. They just need to implement the required methods.Normalized data models
Adapters normalize platform-specific data into two shared models:SessionRecord
Summary record for indexing and listings:ViewerSession
Full session payload for dashboard and extraction:Platform-specific implementations
Lerim includes four platform adapters:Claude Code adapter
Reads JSONL files from~/.claude/projects/:
type: user|assistant|summary entries.
Normalization: Minimal — Claude already uses JSONL. Adapter extracts tool_use/tool_result blocks from content arrays.
Key features:
- Supports multi-block content (text + tool_use in single message)
- Tracks git branch and cwd from session metadata
- Deduplicates via file content hash
src/lerim/adapters/claude.py:40-150 for message parsing logic.
Codex CLI adapter
Reads JSONL files from~/.codex/sessions/:
Session format: Native JSONL similar to Claude.
Normalization: Similar to Claude adapter — Codex uses the same JSONL schema.
Cursor adapter
Extracts sessions from Cursor’s SQLite database:state.vscdb) with table cursorDiskKV.
- Session metadata:
composerData:<composerId>rows - Messages:
bubbleId:<composerId>:<bubbleId>rows
- Query SQLite for all
composerDataandbubbleIdrows - Group bubbles by
composerId - Export each session as JSONL to
~/.lerim/cache/cursor/<composerId>.jsonl - Return
SessionRecordpointing to cached JSONL file
Why export to JSONL cache?
Why export to JSONL cache?
Exporting to JSONL serves three purposes:
- Consistency: Downstream extraction pipeline always reads JSONL, regardless of platform
- Performance: Avoid repeated SQLite queries during sync — read from cached file instead
- Compatibility: Dashboard and extraction pipeline treat all sessions as JSONL files
~/.lerim/cache/cursor/ and is regenerated on each sync.- Platform-specific path detection (macOS vs Linux)
- Double-encoded JSON value parsing (Cursor stores JSON as JSON strings)
- Role normalization (bubble types
1=user,2=assistant) - Hash-based change detection (skip unchanged sessions)
src/lerim/adapters/cursor.py:189-285 for full implementation.
OpenCode adapter
Extracts sessions from OpenCode’s SQLite database: Session format: SQLite database (opencode.db) with chat history table.
Normalization: Similar to Cursor — query SQLite, group by session, export to JSONL cache at ~/.lerim/cache/opencode/.
Default path: ~/.local/share/opencode/ (Linux/macOS)
Session discovery flow
Adapters discover sessions throughiter_sessions():
- Scan: Recursively search
traces_dirfor session files/databases - Filter time window: Skip sessions outside
start/enddatetime range - Hash check: Compare file content hash against
known_run_hashesto skip unchanged sessions - Parse metadata: Extract session start time, repo info, message/tool counts
- Return records: Build
SessionRecordlist sorted by start time
Session normalization to JSONL
All adapters ensure their output is JSONL-compatible:Native JSONL platforms (Claude, Codex)
No conversion needed — sessions are already in JSONL format. Adapter validates structure and extracts metadata.SQLite platforms (Cursor, OpenCode)
Adapters export to JSONL cache:- Cursor:
~/.lerim/cache/cursor/<composerId>.jsonl - OpenCode:
~/.lerim/cache/opencode/<session_id>.jsonl
Adapter registry
Adapters are registered insrc/lerim/adapters/registry.py:
Platform connection
Users connect platforms vialerim connect:
~/.lerim/platforms.json:
See
src/lerim/adapters/registry.py:90-139 for connection logic.How to add a new adapter
To add support for a new coding agent platform:1. Create adapter module
Createsrc/lerim/adapters/yourplatform.py:
2. Register adapter
Add tosrc/lerim/adapters/registry.py:
3. Test connection
default_path(), count_sessions(), and optionally validate_connection() if defined.
4. Export to JSONL if needed
If your platform uses a database format:- Query the database in
iter_sessions() - Export each session to
~/.lerim/cache/yourplatform/<session_id>.jsonl - Return
SessionRecordwithsession_pathpointing to the JSONL file
src/lerim/adapters/cursor.py:189-285 for a complete SQLite-to-JSONL example.
Best practices for adapter implementation
Best practices for adapter implementation
- Use content hashing: Implement hash-based change detection to skip unchanged sessions
- Handle missing paths gracefully: Return empty lists or
Nonewhen paths don’t exist - Normalize timestamps: Use ISO 8601 format for
start_timefields - Extract metadata: Populate
repo_path,repo_name,message_count,tool_call_count, etc. - Cache exports: For database platforms, export to
~/.lerim/cache/yourplatform/and reuse cached files - Add validation: Implement optional
validate_connection()for connection health checks
Next steps
CLI reference
Learn how to connect platforms using the CLI
Contributing
Submit a PR to add a new platform adapter