Metadata-Version: 2.5
Name: netcodex-agent-exporter
Version: 0.3.0
Summary: Local-first exporter for AI agent conversations (Codex, Claude Code, Copilot, Cline, Cursor, Gemini CLI and more) to Markdown.
Project-URL: Homepage, https://gitlab.com/netcodex-tech/agent-conversation-exporter
Project-URL: Repository, https://gitlab.com/netcodex-tech/agent-conversation-exporter
Project-URL: Issues, https://gitlab.com/netcodex-tech/agent-conversation-exporter/-/issues
Author: NetCodex Technology
License-Expression: MIT
License-File: LICENSE
Keywords: ai-agents,claude-code,codex,copilot,cursor,export,markdown,transcripts
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development
Classifier: Topic :: Text Processing :: Markup :: Markdown
Classifier: Topic :: Utilities
Requires-Python: >=3.12
Requires-Dist: pydantic>=2.7
Requires-Dist: typer>=0.12
Provides-Extra: ui
Requires-Dist: fastapi>=0.115; extra == 'ui'
Requires-Dist: python-multipart>=0.0.9; extra == 'ui'
Requires-Dist: uvicorn[standard]>=0.30; extra == 'ui'
Provides-Extra: web
Requires-Dist: fastapi>=0.115; extra == 'web'
Requires-Dist: python-multipart>=0.0.9; extra == 'web'
Requires-Dist: uvicorn[standard]>=0.30; extra == 'web'
Description-Content-Type: text/markdown

# 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](https://github.com/iamgio/quarkdown) binary on `PATH` (no Python extra).

### Local UI

```powershell
netcodex ui            # opens http://127.0.0.1:<port>/#token=... in your browser
netcodex ui --port 8765 --out D:\exports --no-open
```

The UI lists every detected source and its conversations, previews the Markdown
(reasoning / tool output / system context toggles) and exports the selected or all
conversations to a folder you choose, incrementally. It binds to 127.0.0.1 only;
`--host` with a non-loopback address is refused unless `--allow-remote` is given.
Every API call needs the per-launch token from the URL, and requests whose `Host` is
not a loopback name are rejected.

## License

MIT, see [LICENSE](LICENSE).

## Setup (development)

```powershell
uv sync
uv run netcodex --help
```

## Common Commands

```powershell
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:

```powershell
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:

```powershell
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

1. Bump `version` in `pyproject.toml` and `src/netcodex/__init__.py`, merge to `main`.
2. Push a tag `vX.Y.Z` matching 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 variable
   `PYPI_TOKEN` (job skipped when the variable is absent).
3. 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

```powershell
uv run ruff check .
uv run pytest
uv build
npm run diagrams:check
```

## Local Web

Install dependencies once:

```powershell
uv sync
npm install
npm install --prefix web
```

Run the local API and web UI together from one terminal:

```powershell
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:

```powershell
npm run api:dev
npm run web:dev
```

The web UI reads `NEXT_PUBLIC_API_URL`; when it is not set, it uses
`http://localhost:8000`. 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:

- `main` is 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 and `v*` tags are reserved for release preparation.

See `docs/development/gitlab-flow.md` for the full policy.

## Privacy Rules

- Do not commit real exports, raw `.jsonl` files, SQLite databases or local
  attachments.
- Use sanitized fixtures only.
- Keep parsers read-only against source directories.
- Use `--include-paths` only when full local paths are intentionally needed in
  the generated metadata.
