Skip to content

Configuration en

ClarusIubar edited this page Aug 17, 2026 · 3 revisions

Configuration (config.json)

한국어 | English

Three paths — where your raw takeout lives, where converted markdown goes, and where your actual Obsidian vault is — are managed via config.json. It's auto-created with default values in the project root on first run (see the repository's config.example.json for its shape). It contains personal paths, so it's .gitignored.

{
  "takeout_paths": { "chatgpt": "", "gemini": "", "claude": "" },
  "markdown_output_dir": "result",
  "obsidian_vault_dir": "",
  "vault_subdirs": { "chatgpt": "ChatGPT", "gemini": "Gemini", "claude": "Claude" }
}

Priority

CLI flag > config.json > built-in default. If you set nothing, it uses the defaults (source is data/<vendor>/, output is result/, vault is unset). Use a CLI flag to override for a single run, or edit config.json directly if you want to keep using the same location every time.

Path config.json key CLI override Default
Raw takeout source takeout_paths.<vendor> --input VENDOR=PATH data/<vendor>/
Markdown output markdown_output_dir --output-dir PATH result/
Obsidian vault obsidian_vault_dir --vault-dir PATH (with --publish) unset (no publishing)

When applying to the vault with --publish, a per-vendor subfolder is auto-created using the names configured in vault_subdirs (<vault>/ChatGPT/, <vault>/Gemini/, <vault>/Claude/).

Publishing is simple mirroring

Upserts are based purely on the vault_dir/<vendor_subdir>/<filename> location — if you move or rename a note inside your vault, that move isn't tracked, so if that session's content changes later, a new note may be created at the original location rather than wherever you moved it.

The Claude vendor splits project-attached conversations into subfolders — result/claude/<project name>/*.md — and --publish reproduces that subfolder structure as-is when mirroring, at vault_dir/<vendor_subdir>/<project name>/<filename> (common/publish.py recursively walks result_dir). For the same reason, if a Claude project gets renamed later, a new subfolder is created and the old subfolder's file becomes orphaned — the same kind of limitation as the "moves aren't tracked" point above.

How upsert works

Re-converting the same session doesn't unconditionally rewrite it. The frontmatter's content_hash (a SHA-256 of the rendered body) is compared against the previous note to decide created / updated / unchanged. Relying on whether a session_id exists alone can't catch a conversation that was continued later, so the actual rendered output is compared every time instead. --publish reuses the exact same upsert logic (common/upsert.py).

Related pages: Output Format, Architecture

Clone this wiki locally