Metadata-Version: 2.4
Name: chatgpt-export-tool
Version: 1.0.0
Summary: Stream, analyze, and export ChatGPT conversations to Markdown, text, or JSON
Author-email: Void Freud <voidfreud@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/voidfreud/chatgpt-export-tool
Project-URL: Source, https://github.com/voidfreud/chatgpt-export-tool
Project-URL: Issues, https://github.com/voidfreud/chatgpt-export-tool/issues
Keywords: chatgpt,json,export,conversations,parser
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: ijson>=3.2.0
Requires-Dist: tomli>=2.0.0; python_version < "3.11"
Dynamic: license-file

chatgpt-export

**Your ChatGPT history. Clean Markdown. Zero memory overhead.**

 
 
 

[**Install**](#installation)  · 
[**Quick Start**](#quick-start)  · 
[**Formats**](#output-formats)  · 
[**Filtering**](#filtering)  · 
[**Config**](#configuration)  · 
[**Fields Reference**](Fields.md)

Takes your `conversations.json` from ChatGPT and turns it into **clean, readable Markdown** — or plain text, or structured JSON. Uses streaming parsing ([ijson](https://github.com/ICRAR/ijson)) so even 100MB+ exports never hit memory. Every aspect of filtering, formatting, and output is configurable through CLI flags or a single TOML file.

```
$ chatgpt-export export conversations.json --split subject --output-dir vault/

  Exported 824 files to vault/
```


> [!TIP]
> Export straight into your **Obsidian vault** for a fully searchable, linked archive of every conversation you've ever had with ChatGPT.

## Installation

> **Requires Python `3.10+`**  ·  managed with [uv](https://docs.astral.sh/uv/)

```bash
git clone https://github.com/voidfreud/chatgpt-export-tool.git
cd chatgpt-export-tool
uv sync
```


 Dev tooling (pytest, ruff, coverage)

```bash
uv sync --group dev
```


Verify:

```bash
uv run chatgpt-export --help
```


## Quick Start

```bash
# Analyze — stats without loading the whole file
uv run chatgpt-export analyze conversations.json

# Export to markdown on stdout
uv run chatgpt-export export conversations.json

# One markdown file per conversation
uv run chatgpt-export export conversations.json --split subject --output-dir exports/

# JSON dump
uv run chatgpt-export export conversations.json --format json --output dump.json
```


## Output Formats

| Format | Flag | Extension | |
|:--|:--|:--|:--|
| **Markdown** | `--format md` | `.md` | `#` headings, `>` blockquoted context, `---` turn separators. **Default.** |
| **Plain text** | `--format txt` | `.txt` | Indented, plain labels — good for terminals and grep. |
| **JSON** | `--format json` | `.json` | Filtered conversation objects, valid JSON. |

Markdown and text exports follow the **active conversation branch** — you see the conversation as it played out, not the full tree with edits and branches.

 Preview: Markdown output

```markdown
# Opening bank account in Thailand
**ID:** 68ed8eba-1d00-832a-a2f1-4721496ed217
**Created:** 23:43 13-10-2025
**Turns:** 34

## Conversation Context
> User profile: The user provided the following information...
> User instructions: Speaking to Nova. Zero restraint...

## User [23:43 13-10-2025]
Can a foreigner open a Thailand bank account?

---

## Assistant [23:44 13-10-2025]
Yup — a foreigner *can* open a bank account in Thailand, but it's
*much more difficult* now than it used to be...
```


**Default transcript policy:**

| | Shown | Hidden |
|:--|:--|:--|
| | User text, assistant text, thoughts, context (compact) | Tool plumbing, code execution, reasoning recap, blank nodes |

Fully configurable via `[transcript]` in the TOML config.

## Commands

### `analyze`

Structure and statistics — without writing output files.

```bash
uv run chatgpt-export analyze data.json
uv run chatgpt-export analyze data.json --fields          # include field coverage
uv run chatgpt-export analyze data.json --verbose --output analysis.txt
uv run chatgpt-export analyze data.json --debug
```

### `export`

Convert conversations with full control over structure, metadata, and layout.

```bash
uv run chatgpt-export export data.json --fields "groups minimal"
uv run chatgpt-export export data.json --format json --split date --output-dir by-date/
uv run chatgpt-export export data.json --include "model*" --exclude plugin_ids
uv run chatgpt-export export data.json --config chatgpt_export.toml
```


## Filtering

### Structural fields  `--fields`

```bash
--fields all                                  # everything (default)
--fields none                                 # structure only
--fields "include title,create_time,mapping"  # whitelist
--fields "exclude moderation_results"         # blacklist
--fields "groups minimal"                     # named group
```


 Built-in groups

| Group | Fields |
|:--|:--|
| `conversation` | `_id` `conversation_id` `create_time` `update_time` `title` `type` |
| `message` | `author` `content` `status` `end_turn` |
| `metadata` | `model_slug` `message_type` `is_archived` |
| `minimal` | `title` `create_time` `message` |

Full reference: [`Fields.md`](Fields.md)

### Metadata  `--include` / `--exclude`

Runs after structural filtering. Applies to keys inside `message.metadata`.

```bash
--include model_slug
--include "model*" --exclude plugin_ids       # glob patterns
```


## Split Modes

| Mode | Flag | Output |
|:--|:--|:--|
| **single** | `--split single` | One stream or file *(default)* |
| **subject** | `--split subject` | `Title_ID.md` per conversation |
| **date** | `--split date` | Daily folders |
| **id** | `--split id` | Named by conversation ID |

> [!NOTE]
> `--output` is for single mode. Split modes use `--output-dir`.

## Configuration

Persist defaults in a single TOML file. The repo ships [`chatgpt_export.toml.example`](chatgpt_export.toml.example).

```bash
cp chatgpt_export.toml.example chatgpt_export.toml
uv run chatgpt-export export data.json --config chatgpt_export.toml
```

CLI flags always override TOML values.

 TOML reference

**`[defaults]`** — format, split, fields, output directory, metadata

**`[transcript]`** — branch following and visibility

| Key | Default | |
|:--|:--|:--|
| `show_system_messages` | `false` | System prompts |
| `show_tool_messages` | `false` | Tool/function calls |
| `show_assistant_code` | `false` | Code execution |
| `show_reasoning_recap` | `false` | Reasoning summaries |
| `user_editable_context_mode` | `"compact"` | `"compact"` or `"full"` |

**`[text_output]`** — layout and formatting

| Key | Default | |
|:--|:--|:--|
| `layout_mode` | `"reading"` | `"reading"` or `"compact"` |
| `heading_style` | `"markdown"` | `"markdown"` or `"plain"` |
| `turn_separator` | `"---"` | Between turns |
| `strip_chatgpt_artifacts` | `true` | Remove citation artifacts |
| `wrap_width` | `88` | `0` to disable |

 Presets

**Reading-first** *(default)*
```toml
[text_output]
layout_mode = "reading"
heading_style = "markdown"
strip_chatgpt_artifacts = true
wrap_width = 88
```

**Compact**
```toml
[text_output]
layout_mode = "compact"
turn_separator = ""
wrap_width = 0
```

**Terminal**
```toml
[defaults]
format = "txt"

[text_output]
heading_style = "plain"
```


## Architecture

```
chatgpt_export_tool/
├── cli.py                  ← entry point
├── commands/               ← analyze, export
└── core/
    ├── parser.py           ← streaming JSON (ijson)
    ├── filter_pipeline.py  ← field + metadata filtering
    ├── export_service.py   ← orchestration
    ├── config/             ← TOML loading & validation
    ├── transcript/         ← branch reconstruction
    ├── validation/         ← field & metadata checks
    └── output/             ← formatters, writer, paths
```

Modular by design — filtering, formatting, splitting, and writing are separate concerns.

## Development

```bash
uv run pytest
uv run pytest --cov=chatgpt_export_tool --cov-report=term-missing
uv run ruff check chatgpt_export_tool tests
uv run ruff format --check chatgpt_export_tool tests
```


[MIT](LICENSE)  ·  built by [@voidfreud](https://github.com/voidfreud)

