Privacy-conscious, schema-aware extraction of local coding-agent session JSONL. The canonical package and command support both Codex rollouts and current Claude Code project JSONL. No network access, telemetry, or runtime dependencies are required.
From GitHub:
pipx install git+https://github.com/shiftedx/coding-agent-session-extractor.git
# or: python -m pip install git+https://github.com/shiftedx/coding-agent-session-extractor.gitFrom a checkout:
python -m pip install -e ".[dev]"Auto discovery scans $CODEX_HOME or ~/.codex and $CLAUDE_HOME or ~/.claude.
Claude discovery reads projects/**/*.jsonl, excludes root history.jsonl, and excludes
agent-*.jsonl unless subagents are requested.
coding-agent-session-extractor --provider auto --format normalized-v2 --output export.jsonl
coding-agent-session-extractor --provider claude-code --claude-home ~/.claude --include-subagents
coding-agent-session-extractor --provider codex --codex-home ~/.codexExplicit files are provider-detected in auto mode. Explicit directories and files are sorted deterministically. Symlinks and resolved paths outside the selected root are rejected. The legacy command remains available and is Codex-only:
codex-jsonl-extractor --format normalized-v2
python -m codex_jsonl_extractornormalized-v2 is the canonical format. It emits one JSON object per session with
schema_version, source (codex or claude-code), session_id, ordered typed
events, deterministic sequence, provenance, and compatibility messages and
tool_results projections. Claude events use the shared kinds message, reasoning,
tool_call, tool_result, attachment, lifecycle, and metadata. Claude UUID, parent UUID, sidechain, agent ID, and parent-session relationships are
retained. Included subagent files become distinct sessions keyed by (sessionId, agentId)
instead of being folded into their parent transcript.
legacy-v1 preserves the original consumer shape and works for both providers. Claude
records have source: "claude-code".
Sensitive material is opt in:
coding-agent-session-extractor --provider claude-code --include-reasoning --include-tool-input --include-tool-output --include-attachments --path-mode relative --output reviewed.jsonlBy default, conversation text is retained, while reasoning text, tool input, tool
output, attachment/image/file-history content, developer messages, and path metadata
are omitted. Queue-operation content, last-prompt content, arbitrary unknown fields,
URLs, and raw auxiliary payloads never leak by default. --path-mode full|relative|omit
controls cwd, git branches, pull-request and file paths. --include-paths is a
compatibility alias for --path-mode full.
Inventory and dry-run modes are schema-only and emit bounded allowlisted type and key shapes without record values:
coding-agent-session-extractor --provider auto --inventoryThe defaults bound line size (10 MiB), files (2048), total input (5 GiB), records
(1,000,000), events (2,000,000), output (1 GiB), and inventory output (1 MiB). Each
limit is configurable. Output is serialized and counted incrementally before stdout
publish; file output is streamed into the unpublished atomic temporary file. Writes
refuse replacement unless --overwrite is provided and use mode 0600 on POSIX.
Codex roots contain sessions/**/rollout-*.jsonl; archived rollouts are included by
default and can be disabled with --no-include-archived. The old package, module,
console script, normalized shape, legacy shape, and flags remain compatible.
Claude roots contain project main session files and optional agent-*.jsonl sidechains.
Assistant text and user text become messages. Thinking becomes reasoning, tool_use
becomes a tool call, and tool_result remains a distinct linked result. id and
tool_use_id are normalized as call_id. sourceToolAssistantUUID and
sourceToolUseID relationships are preserved when present. Numeric and RFC3339
timestamps are accepted. Queue operations and known system/compaction records become
value-minimized lifecycle events; their content is never copied by default. Auxiliary
records remain schema-only unless an explicit safe path or content opt-in applies.
Install the generic distribution, change the command to
coding-agent-session-extractor, and use --provider codex for an explicit Codex
contract. Existing automation can continue using codex-jsonl-extractor and
python -m codex_jsonl_extractor; they retain Codex defaults. Consumers should migrate
to the canonical package name and select --format legacy-v1 during a staged rollout.
python -m venv .venv
. .venv/bin/activate
python -m pip install -e ".[dev]"
ruff check .
pytest
python -m build
python -m compileall -q srcUse synthetic fixtures only. The MIT license is in LICENSE; security handling is in
SECURITY.md, contributor policy is in CONTRIBUTING.md, and the schema contract is in
docs/ARCHITECTURE.md.