NetCodex Agent Conversation Exporter
Private, local-first CLI for exporting AI agent conversations from Claude Code and Codex into Markdown, Quarkdown and PDF.
Status
Version 0.2 ("correct exports"). Supported sources:
| Source | Where it is read from | Client labels (tool) |
|---|---|---|
| Codex CLI / VS Code extension / Codex Desktop | $CODEX_HOME or ~/.codex: newest state_*.sqlite (threads, thread_spawn_edges), session_index.jsonl titles, rollout JSONL in sessions/ and archived_sessions/ |
codex-cli, codex-vscode, codex-desktop |
| Claude Code CLI / VS Code | $CLAUDE_CONFIG_DIR/projects or ~/.claude/projects/**/<session>.jsonl; subagents in <session>/subagents/agent-*.jsonl are grouped under their parent |
claude-code-cli, claude-code-vscode |
| Claude desktop "Code" tab | Same JSONL, titled from %APPDATA%/Claude/claude-code-sessions/**/local_*.json |
claude-desktop |
| Claude desktop Cowork | %APPDATA%/Claude/local-agent-mode-sessions/**/local_<id>.json + local_<id>/.claude/projects/**/*.jsonl |
claude-cowork |
GitHub Copilot Chat (copilot-chat) |
<editor>/User/workspaceStorage/*/chatSessions/*.jsonl (operation log) or .json, globalStorage/emptyWindowChatSessions in every VS Code-family editor |
copilot-chat-<editor> |
Cline / Roo Code / Kilo Code (cline) |
<editor>/User/globalStorage/<extension>/tasks/<id>/api_conversation_history.json |
cline-*, roo-code-*, kilo-code-* |
Cursor (cursor) |
Cursor/User/globalStorage/state.vscdb (cursorDiskKV composer + bubbles) |
cursor |
GitHub Copilot CLI (copilot-cli) |
~/.copilot/session-state/<id>/events.jsonl |
copilot-cli |
Gemini CLI (gemini-cli) |
~/.gemini/tmp/<hash>/chats/session-*.json, logs.json |
gemini-cli |
Continue (continue) |
~/.continue/sessions/*.json |
continue |
Aider (aider) |
.aider.chat.history.md in repos under NETCODEX_AIDER_PATHS or the home folder (depth 3) |
aider |
claude.ai chats (claude-ai) |
Official export ZIP / conversations.json from NETCODEX_CLAUDE_AI_EXPORT or ~/Downloads |
claude-ai |
Google Antigravity (antigravity) |
~/.gemini/antigravity/conversation_summaries.db + conversations/*.db (schemaless protobuf, best effort; legacy encrypted .pb skipped) |
antigravity |
Trae, Windsurf (trae, windsurf) |
Encrypted stores: reported by netcodex sources, not exported |
- |
All parsers map to one canonical model (Conversation -> Turn -> MessagePart
with text, tool_call, tool_result, reasoning, image, attachment,
system_context and summary parts). Tool results are attached to their call,
injected environment/instruction/hook context is classified as system context,
and mirrored Codex event_msg messages are de-duplicated.
Raw conversations stay local by default. Generated exports are written under
exports/, which is intentionally ignored by Git.
Install
NetCodex runs on your own machine; it reads the local conversation stores and never uploads them. Python 3.12+ is required for the package installs.
| How | Command | Notes |
|---|---|---|
| pipx | pipx install "netcodex-agent-exporter[ui]" |
Recommended. Drop [ui] for the CLI only. |
| uv | uv tool install "netcodex-agent-exporter[ui]" |
Same, using uv. |
| Binary | Download netcodex-<version>-windows-x86_64.exe or -linux-x86_64 from the GitLab Release |
Single file, no Python needed; includes the UI. |
| From source | git clone ... && uv sync && uv run netcodex --help |
For development. |
The PyPI package and release binaries are published from v* tags (first release:
v0.3.0). Extras: [ui] (alias [web]) adds FastAPI/uvicorn for netcodex ui and the
upload API; the core CLI only needs Pydantic and Typer. PDF export needs the external
Quarkdown binary on PATH (no Python extra).
Local UI: the Conversation export desk
netcodex ui # opens http://127.0.0.1:<port>/app/#token=... in your browser
netcodex ui --port 8765 --out D:\exports --no-open
netcodex --version
netcodex ui serves the full export desk from your own machine: an upload rail for
JSONL/SQLite/ZIP files with source auto-detection, a Local sources tab that reads the
detected tools directly (Codex, Claude Code, Copilot, Cline, Cursor, Gemini CLI, ...),
MD/QD/PDF formats with Quarkdown templates, the Upload > Analyze > Review > Export > Done
tracker, a system activity log, the Markdown/HTML preview and the export summary with the
ZIP download. QD and PDF need the Quarkdown CLI; the desk says so when it is missing.
Everything runs on 127.0.0.1: --host with a non-loopback address is refused unless
--allow-remote is given, API calls need the per-launch token from the URL (exchanged
for an HttpOnly, SameSite=Strict session cookie), and requests whose Host is not a
loopback name are rejected. Nothing is sent to a NetCodex server.
The desk is the Next.js app in web/, built as a static site by npm run desk:build
(scripts/build-desk.mjs) into src/netcodex/web/desk/ and shipped in the wheel. A
source checkout without that build falls back to a minimal built-in page.
License
MIT, see LICENSE.
Setup (development)
uv sync
uv run netcodex --help
Common Commands
uv run netcodex sources # registered sources, found / not found
uv run netcodex scan --sources all
uv run netcodex analyze --source auto --json
uv run netcodex export --all --out exports # every available source, every session
uv run netcodex export --all --since 7d --workspace my-repo
uv run netcodex export --source claude --formats md,qd --limit 1
uv run netcodex export --local --source codex --formats md,qd,pdf --template galactic-guide --json
uv run netcodex validate exports
export accepts --source auto|all|<name>[,<name>] (or --all), --limit N per
source (default 0 = all sessions), --since/--until (ISO date or an age such
as 7d, 12h, 2w) and --workspace <text> (case-insensitive match on the
session's working directory). Tool inputs/outputs are capped per block with
--max-tool-output-lines (default 200) and --max-tool-output-bytes (default
32000); the Markdown notes how much was left out. Payloads over 200k characters
are also cut at import time, before redaction.
Exports are incremental: <out>/.netcodex-state.json records a fingerprint of
each session's source files (size and mtime, including subagent files), its title
and the export options. Re-running export into the same folder only re-renders new
or changed conversations (renamed ones replace their old folder); --force
re-exports everything and --no-incremental ignores the state file. To keep a
folder up to date continuously:
uv run netcodex watch --out exports --interval 60 # Ctrl+C to stop
Large exports use worker processes (--jobs, default automatic, up to 4).
Sources live in a registry (netcodex.sources.registry). Store locations come
from a per-platform path matrix (netcodex.sources.paths: Windows
%APPDATA%, macOS ~/Library/Application Support, Linux ~/.config) that also
enumerates VS Code-family editors (Code, Insiders, VSCodium, Cursor, Windsurf,
Trae, Antigravity, Kiro, Positron).
Each export creates one folder per conversation named
<source>/<date>-<title-slug>-<short-id>/ containing conversation.md,
metadata.json and netcodex-manifest.json, plus an index.md table (date,
title, tool, turns, link) at the export root.
conversation.md (Markdown v2) starts with YAML frontmatter (title, id,
source, tool, originator, model, workspace, git_branch,
started_at, ended_at, turn_count, subagent_count, parent_id), uses one
## Role · timestamp heading per turn, keeps code fences intact and puts tool
calls/results and reasoning in collapsible <details> blocks. Images and
attachments become placeholders. Content switches:
uv run netcodex export --source codex --limit 20 `
--no-reasoning --no-tool-output --include-system-context --no-subagents `
--max-tool-output-lines 50
Every export records the shared workflow analyze -> parse -> render -> package
inside netcodex-manifest.json, including generated artifact hashes without
storing transcript bodies.
PDF export uses Quarkdown for the MVP. If Quarkdown or its browser runtime is not available, the CLI reports the missing dependency instead of failing silently.
Releasing
- Bump
versioninpyproject.tomlandsrc/netcodex/__init__.py, merge tomain. - Push a tag
vX.Y.Zmatching that version. The tag pipeline builds the sdist and wheel, PyInstaller single-file binaries for Linux and Windows (GitLab.com Windows runner), uploads everything to the project's generic package registry, creates the GitLab Release, and publishes to PyPI with the masked, protected CI/CD variablePYPI_TOKEN(job skipped when the variable is absent). - macOS binaries need a macOS runner; build them locally with
uv run pyinstaller --onefile --name netcodex --collect-submodules netcodex --collect-submodules uvicorn --collect-data netcodex scripts/netcodex_entry.py.
Development
uv run ruff check .
uv run pytest
uv build
npm run diagrams:check
Local Web
Install dependencies once:
uv sync
npm install
npm install --prefix web
Run the local API and web UI together from one terminal:
npm run dev
This starts:
- API:
http://localhost:8000 - Web:
http://127.0.0.1:3100
You can still run each side separately when debugging:
npm run api:dev
npm run web:dev
In development (npm run dev) the desk reads NEXT_PUBLIC_API_URL (default
http://localhost:8000) and the dev API also serves the local-sources endpoints. The MVP web flow accepts .jsonl, .sqlite, and
.zip uploads, analyzes detected Claude/Codex sessions, previews Markdown,
and downloads generated artifacts plus netcodex-manifest.json as a ZIP.
Public landing deployment (landing-only mode)
The web app can be deployed publicly as a marketing site (e.g. Dokploy/Nixpacks
with build path web, npm run build then npm run start). Because the export
workspace needs the local API, a production build runs in landing-only mode
when NEXT_PUBLIC_LANDING_ONLY=1 is set, or when NEXT_PUBLIC_API_URL is unset:
/app shows a "This tool runs locally" panel with install instructions instead
of the upload form, and every "Open app" call to action points to /install.
Set NEXT_PUBLIC_LANDING_ONLY=0 to force the full workspace in a production
build. next dev always keeps the local workspace.
See docs/web/local-web-api.md for the API contract and temporary file cleanup
policy.
Architecture
The canonical architecture model lives in docs/architecture/likec4/model.c4
and is validated with LikeC4. GitLab-friendly Mermaid mirrors live in
docs/architecture/c4.md.
VS Code users should open the .c4 file with the LikeC4 extension installed.
The expected extension id is likec4.likec4-vscode.
GitLab Flow
NetCodex uses GitLab Flow, not Git Flow:
mainis protected and always releasable.- Work starts from issue branches named
issue/<iid>-<short-slug>. - Every change goes through a merge request into
main. - Merge requires a green pipeline and resolved discussions.
release/*branches andv*tags are reserved for release preparation.
See docs/development/gitlab-flow.md for the full policy.
Privacy Rules
- Do not commit real exports, raw
.jsonlfiles, SQLite databases or local attachments. - Use sanitized fixtures only.
- Keep parsers read-only against source directories.
- Use
--include-pathsonly when full local paths are intentionally needed in the generated metadata.
Metadata
Release files for netcodex-agent-exporter 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| netcodex_agent_exporter-0.3.1.tar.gz | 2.4 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| netcodex_agent_exporter-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 4.9 MB
Release files / netcodex_agent_exporter-0.3.1.tar.gz
| Download URL | netcodex_agent_exporter-0.3.1.tar.gz |
|---|---|
| Size | 2.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cf1a6a98000577fb6f105815fbec972c681461680a39d301a9b366dab783d68b
|
|
BLAKE2b-256 checksum How to use checksums |
f0180cb3e28f444415fdc849641a4140ea070a4783bd0132f7ca60f3fb730de6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / netcodex_agent_exporter-0.3.1-py3-none-any.whl
| Download URL | netcodex_agent_exporter-0.3.1-py3-none-any.whl |
|---|---|
| Size | 2.5 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9cb03a67c189db350b20252d4983137b34339562ebda9b06dfb4cb44739dfd07
|
|
BLAKE2b-256 checksum How to use checksums |
683064430c80d9d27eb1c59499371cabc441c64b5bc300fa6b76419798318439
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|