Metadata-Version: 2.4
Name: obsivault
Version: 0.2.0
Summary: Convert AI chat exports (Claude, Grok, ChatGPT, Gemini) into an Obsidian-friendly Markdown vault.
Project-URL: Homepage, https://github.com/andrijdavid/obsivault
Project-URL: Issues, https://github.com/andrijdavid/obsivault/issues
Author: andrijdavid
License: AGPL-3.0-or-later
License-File: LICENSE
Keywords: chatgpt,claude,export,gemini,grok,markdown,obsidian
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Text Processing :: Markup :: Markdown
Requires-Python: >=3.11
Requires-Dist: beautifulsoup4>=4.12
Requires-Dist: ijson>=3.2
Requires-Dist: markdownify>=0.11
Requires-Dist: pydantic>=2.6
Requires-Dist: python-slugify>=8
Requires-Dist: pyyaml>=6
Requires-Dist: rich>=13
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-cov>=5; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Requires-Dist: types-pyyaml; extra == 'dev'
Description-Content-Type: text/markdown

# obsivault

Convert your AI chat exports into a tidy Obsidian Markdown vault. One note per
conversation, YAML frontmatter, attachments copied into a sibling folder, and
an idempotent state file so re-running only touches what changed.

Supported sources (v0.1):

- **Claude** (Settings -> Privacy -> Export). Reads `conversations.json`.
- **Grok** (Settings -> Data controls -> Export). Reads `prod-grok-backend.json`.
- **ChatGPT** (Settings -> Data controls -> Export). Reads the `conversations.json` tree.
- **Gemini** via Google Takeout (My Activity -> Gemini Apps and Gemini in
  Workspace). Reads the Workspace transcripts and, optionally, NotebookLM.

## Install

From PyPI:

```sh
pip install obsivault
```

Or with uv:

```sh
uv tool install obsivault
```

From source (for development):

```sh
uv sync
```

## Usage

```sh
uv run obsivault providers
uv run obsivault convert ./data/claude  ./vault --provider claude
uv run obsivault convert ./data/grok    ./vault --provider grok
uv run obsivault convert ./data/google  ./vault --provider gemini
```

Useful flags:

- `--include-tools` show tool calls as collapsible callouts
- `--include-thinking` show Claude thinking blocks as collapsible callouts
- `--branches` render alternate branches as `> [!example]-` callouts
- `--no-copy-attachments` skip the attachment copy step
- `--dry-run` plan-only, no writes
- `--force` rewrite even when content hash is unchanged

## Layout

```
vault/
  claude/2026-04/<slug>.md
  grok/2026-05/<slug>.md
  gemini/2026-03/<slug>.md
  _attachments/<provider>/<conv-id>/...
  .obsivault/state.json
```

## Adding a provider

Drop a module under `src/obsivault/providers/<name>.py` with a class that
implements `Provider` and is decorated with `@register`. The CLI auto-detects
sources by calling each provider's `discover()`.

## Licence

AGPL-3.0-or-later. PRs welcome.
