Metadata-Version: 2.4
Name: agent-migrator
Version: 0.1.0
Summary: Migrate conversation history between AI coding agents
Project-URL: Homepage, https://github.com/builderpepc/agent-migrator
Project-URL: Repository, https://github.com/builderpepc/agent-migrator
Author-email: Troy Gunawardene <gunawardene.t@northeastern.edu>
License: CC-BY-SA-4.0
License-File: LICENSE
Requires-Python: >=3.10
Requires-Dist: notify-py>=0.3.43
Requires-Dist: questionary>=2.1.1
Requires-Dist: rich>=15.0.0
Description-Content-Type: text/markdown

# agent-migrator

A CLI tool for migrating conversation history between AI coding tools.

## Supported Coding Agents

- **Claude Code** (Anthropic)
- **Codex** (OpenAI)
- **Gemini CLI** (Google)
- **Cursor**

All pairs are supported bidirectionally.

---

## Setup

Requires [uv](https://docs.astral.sh/uv/).

**Install globally** (recommended):

```bash
uv tool install git+https://github.com/builderpepc/agent-migrator.git
```

**Or run without installing:**

```bash
uvx agent-migrator
```

---

## Usage

### Interactive

Run from inside a project directory:

```bash
agent-migrator
```

The CLI walks you through:

1. **Tool selection** — choose source and destination.
2. **Conversation selection** — pick conversations to migrate, sorted most-recent-first.
3. **Migration progress** — each conversation is processed in sequence; `Ctrl+C` cancels and rolls back.
4. **Summary** — a results table shows successes and errors.

> **Cursor:** the project path must be a directory that has been opened as a workspace in Cursor at least once.

### Non-interactive

Two subcommands expose the same engine for scripting and agentic use. Both accept `--dir <path>` (defaults to cwd) and print JSON to stdout; errors go to stderr as `{"error": "..."}` with exit 1.

**List conversations:**

```bash
agent-migrator list --from claude-code --dir /path/to/project
```

```json
[{"id": "63ec7bb1-...", "name": "pwa-capabilities-demo", "updated_at": "2026-05-21T23:23:00", ...}]
```

**Migrate a conversation:**

```bash
agent-migrator move --from claude-code --to codex --id 63ec7bb1-... --dir /path/to/project
```

```json
[{"source_id": "63ec7bb1-...", "destination_id": "019e51f7-...", "name": "pwa-capabilities-demo"}]
```

Omit `--id` to migrate all conversations for the project. Run `agent-migrator list --help` or `agent-migrator move --help` for full options.

---

## What gets migrated

All pairs support:

| Feature | Status |
|---|---|
| Text messages (user and assistant) | ✓ |
| Tool calls (Read, Write, Edit, Bash, Glob, and equivalents) | ✓ |
| Plan (presented natively in the destination tool's plan UI) | ✓ |

**(Any) → Cursor** is the one exception: plans are migrated as context documents but are not surfaced in Cursor's native plan mode UI.

**(Any) → Cursor** also requires a server upload to Cursor's `ConvertOALToNAL` endpoint to make all models available. If that fails (e.g. not logged in), the CLI offers a local fallback that provides full context but restricts model selection to Anthropic models.

---

## How it works

Conversations are read into a tool-agnostic normalized format (`TextMessage` and `ToolCallMessage` turns) and written out in the destination format. Each tool is implemented as a `AgentAdapter` subclass in `agent_migrator/agents/`. This decouples all source/destination pairs — adding a new tool requires only a new adapter; all existing migration paths continue to work unchanged.

### Extensibility

To add support for a new coding agent, implement the `AgentAdapter` interface in `agent_migrator/agents/` and register it in `cli.py`:

```python
class MyAgentAdapter(AgentAdapter):
    name = "My Agent"
    tool_id = "myagent"

    def is_available(self) -> bool: ...
    def list_conversations(self, project_path: Path) -> list[ConversationInfo]: ...
    def read_conversation(self, conv_id: str, project_path: Path) -> Conversation: ...
    def write_conversation(self, conv: Conversation, project_path: Path, *, use_local_backend: bool = False) -> str: ...
    def delete_conversation(self, conv_id: str, project_path: Path) -> None: ...
```

### Storage locations

| Tool | Location |
|---|---|
| **Claude Code** | `~/.claude/projects/<encoded-path>/<session>.jsonl` |
| **Codex** | `~/.codex/sessions/YYYY/MM/DD/rollout-<timestamp>-<id>.jsonl` |
| **Gemini CLI** | `~/.gemini/tmp/<project-slug>/chats/session-<timestamp>-<id>.jsonl` |
| **Cursor** | `%APPDATA%/Cursor/User/globalStorage/state.vscdb` (SQLite) |
