Metadata-Version: 2.5
Name: aim-migrate
Version: 0.6.1
Summary: AIM — Agent Identity Migration: harness- and OS-agnostic AI agent state migration (Samsung Smart Switch for AI agents)
License: MIT
License-File: LICENSE
Requires-Python: >=3.10
Requires-Dist: click>=8.0
Requires-Dist: cryptography>=41.0
Requires-Dist: pydantic>=2.0
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# AIM — Agent Identity Migration

[![tests](https://github.com/roryquarrier/aim/actions/workflows/tests.yml/badge.svg)](https://github.com/roryquarrier/aim/actions/workflows/tests.yml)
[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue)](https://pypi.org/project/aim-migrate/)
[![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
[![age-compatible vault](https://img.shields.io/badge/vault-age%20v1%20compatible-8A2BE2)](SECURITY.md)

**Install:** `pipx install aim-migrate` (or `pip install aim-migrate`) — then `aim export` / `aim import`. 100% local, no account, no telemetry.

![What AIM does](docs/infographic.png)

**"Samsung Smart Switch" for AI agents:** migrate a stateful agent's persona,
memories, skills, cron jobs, config, and MCP bindings between *harnesses*
(Hermes ↔ OpenClaw ↔ Claude Code ↔ Codex CLI ↔ OpenCode ↔ Goose ↔ Buzz ↔ Grok Build ↔
DeepSeek Harness ↔ Roo Code) and *operating systems* (Linux, WSL2, macOS, Windows).

Uses a neutral **Canonical Intermediate Format** (`.aim` zip bundle) so migration
is N adapters, not N² point-to-point converters. Design spec: see
`docs/SPEC.md` (v2, Opus-reviewed).

## Quick start (dev, zero-install)

```bash
cd ~/projects/aim
export PYTHONPATH=src

# Export the live Hermes agent (redaction gate blocks if secrets detected)
python3 -m aim.cli export --harness hermes --home ~/.hermes -o agent.aim

# Preview what lands where before writing anything
python3 -m aim.cli plan agent.aim --harness openclaw

# Import into another harness home (transactional: backup + atomic swap)
OPENCLAW_HOME=/path/to/.openclaw python3 -m aim.cli import agent.aim \
    --harness openclaw --force --map /home/hal=/Users/rory

python3 -m aim.cli list agent.aim
python3 -m aim.cli adapters list
```

Requires: python3 with `click pydantic pyyaml cryptography pytest`.

## Adapters

| Harness | Persona | Memory | Skills | Config | MCP | Cron |
|---|---|---|---|---|---|---|
| Hermes | SOUL.md | memories/ | skills/ | yaml | ✓ | ✓ |
| OpenClaw | personality | memory store | skills | json | ✓ | ✓ |
| Claude Code | CLAUDE.md | projects/*/memory | skills/ | — | .claude.json | park |
| Codex CLI | AGENTS.md | — | skills/ + .agents/skills | config.toml | — | park |
| OpenCode | AGENTS.md | — | skills/ | opencode.json | — | park |
| Goose | AGENTS.md | sessions (opt-in) | skills/ | config.yaml | extensions | park |
| Buzz | personas/ | relay-side (opt-in) | skills/ | agents/*.yaml | dev-mcp | workflows |
| Grok Build | AGENTS.md | — | skills/ | settings.json | — | park |
| DeepSeek Harness | AGENTS.md | sessions (opt-in, opaque) | skills/ + .agents/skills | settings.yaml + patch layers | plugins | park |
| Roo Code | default-mode roleDefinition | rules/ | skills/ | cli-settings.json | mcp_settings.json | park |

## Testing

- `pytest tests/` — 31 unit/round-trip tests
- CI matrix: ubuntu + macOS + Windows on every push
- `tests/e2e/container_test.sh` — fully isolated Docker E2E (repo read-only,
  throwaway workdir, `--network none`): secrets leak check, wrong-passphrase
  rejection, cross-harness imports, full suite

## Guarantees

- **Integrity**: every file sha256-hashed in manifest; import refuses on any mismatch
- **Secrets**: gitleaks-style redaction scan at export; export *fails* on
  secret-like spans unless `--allow-unredacted`. Optional `--with-secrets`
  builds an encrypted vault (age-style scrypt + ChaCha20-Poly1305) inside the
  bundle; `import --passphrase` restores values byte-exact
- **Transactionality**: staged copy → validate → atomic rename; 0600 backup;
  refuses if target harness process is running (override `--force`)
- **Lossless-first**: skills copy verbatim (mode bits preserved); unsupportable
  items (e.g. cron jobs into Claude Code) are parked to `unsupported/`, never dropped silently
- **Cross-OS paths**: `--map src=dst` rewrites path references; all rewrites logged

## Status (v0.1, 2026-10-14)

- ✅ Hermes ↔ OpenClaw + Claude Code, Linux — 15/15 tests, live-agent E2E verified
- 🔜 v1.1: age-encrypted secrets vault, native Windows, real-OpenClaw layout verification
- 🔜 v2: Codex/Kilo adapters, container cross-OS test matrix

## Known-history bugs (kept for the record)

- `def list()` in cli.py shadowed builtin `list` → `list(maps)` executed the
  `aim list` click command (fixed, regression test in tests/test_roundtrip.py)
