Skip to main content

harness-distill

Switch AI coding tools without losing what your old tool learned about your project.

You've been building a project with an AI coding assistant such as Claude Code, Cursor or Codex. Over weeks it learned your conventions, which approaches failed, which pull request is waiting on what, and what you planned next. Then you open the same project in a different assistant, and it knows none of that.

harness-distill fixes this. It reads the chat history your old assistants saved for the project and writes the important parts into two plain text files. Any assistant reads them when it opens the project:

File What's in it Commit it to git?
AGENTS.md Lasting rules: how the project is built and tested, your conventions, decisions and why, known pitfalls Yes
.agents/HANDOFF.md Where you left off: recent work, open branches and PRs, next steps No, it stays on your machine

Works with Claude Code, Codex, pi, Cursor, VS Code Copilot, Antigravity and Gemini CLI, in any direction.

Before you start

You need:

  1. At least one AI coding assistant that can run terminal commands. Any of the tools above works.
  2. Python 3.8 or newer. Check with python3 --version.
  3. uv, a Python tool installer. Check with uv --version. If it's missing, install it:
    curl -LsSf https://astral.sh/uv/install.sh | sh
    
    (Windows: powershell -c "irm https://astral.sh/uv/install.ps1 | iex". More options are on uv's install page.)

Quick start

Step 1. Install. Run these in your terminal:

uv tool install harness-distill
harness-distill install

The second command adds the skill to your assistants. You should see two ok lines. Restart any assistant that is already open so it notices the new skill.

Step 2. Distill your project. In your terminal, go to your project folder and start an assistant:

cd ~/work/my-app      # your project folder
claude                # or: pi, codex, agy … or open the folder in Cursor / VS Code

Then type this in the assistant's chat, not in the terminal:

Use the harness-distill skill on this project.

The assistant reads your past sessions, checks them against git, and writes AGENTS.md and .agents/HANDOFF.md. It shows you what it wrote. Read both files and fix anything that's wrong. Then commit AGENTS.md:

git add AGENTS.md && git commit -m "Add AGENTS.md"

Step 3. Continue in the new tool. Open the project in the assistant you are switching to, and ask in its chat:

What is this project, what was I last working on, and what's next?

If it answers correctly, you're done.

Every day after that: when you finish working, tell the assistant "I'm done for today". It updates HANDOFF.md, so whichever tool you open next starts where you stopped. You don't need to run the skill again.

What the result looks like

An example AGENTS.md for a small web app:

# my-app
Flask API + React front end for internal expense reports.

## Rules
- Use `uv`, not pip: the Docker build depends on uv.lock.
- All money values are integer cents. Floats caused rounding bugs (PR #41).
- Never edit `migrations/` by hand; run `make migration name=...`.

## Build and test
- `make dev` starts both servers; `make test` runs pytest + vitest.

## Session handoff
Recent history and open threads are in `.agents/HANDOFF.md` (local only).
Read it at the start of a session; update it before you end one.

HANDOFF.md is similar, but holds the current state: "PR #52 (CSV export) waiting for review; next: add pagination to /reports".

Troubleshooting

Problem Fix
The assistant doesn't know the skill Restart the assistant. In pi, /reload also works. Check that ~/.agents/skills/harness-distill/SKILL.md exists. Run harness-distill install again if it doesn't.
"0 sessions" or very little history found You may have started those sessions from a parent folder. Ask the assistant to use --include-parents. If you only used a tool this skill can't read yet (see below), there's nothing to import.
The new assistant ignores AGENTS.md Claude Code reads CLAUDE.md: create one containing just the line @AGENTS.md. Gemini CLI reads GEMINI.md: put @AGENTS.md in one. Antigravity needs version 1.20.3 or newer.
harness-distill: command not found Run uv tool update-shell, then open a new terminal.
The files contain something private or wrong Edit or delete it. They're plain text, and nothing is uploaded anywhere.

Tested on Linux. macOS and Windows paths are included for Cursor and VS Code, but are untested. Please open an issue if something doesn't work.

Words used here

  • Harness / assistant: the app around the AI model, such as Claude Code, Cursor or Codex. Each one saves its own chat history, which the others can't read.
  • Skill: a folder of instructions (SKILL.md) that an assistant loads when a task needs it. This project is one. See agentskills.io.
  • Distill: keep only what matters. A month of chats becomes a few hundred lines of facts and rules.
  • AGENTS.md: a standard file name for instructions to AI coding assistants. Most of them read it automatically. See agents.md.

For experienced users

Distill, don't migrate

Other tools convert or resume a single session in another tool. This one works at the project level:

  • It merges every harness. It reads all of a folder's sessions from all of your tools. The first real run found 10 sessions across Claude Code, Codex and pi.
  • It distills instead of replaying. A 1.5 MB transcript makes worse context than a 3 KB brief. Tool output and thinking are dropped. Prompts, decisions and outcomes are kept.
  • It checks claims against git. Claims about branches, PRs and failing tests are checked against the repo before they are written down. Anything that can't be confirmed is marked (?) rather than guessed.
  • It is scoped to the project. Unrelated side work done in the same chats is left out.
  • It stays current. The end-of-session rule in AGENTS.md keeps the handoff current without re-running the skill.
  • It reads GUI IDE history too: Cursor IDE, VS Code Copilot Chat, and Antigravity's artifacts.

To resume one exact conversation in another tool, use session-migrate or continues. The two approaches work well together.

What it reads

Harness Source What you get
Claude Code (CLI and IDE extension) ~/.claude/projects/<slug>/*.jsonl, memory/*.md Full transcripts, compaction summaries, auto-memory
Codex (CLI and IDE extension) ~/.codex/sessions/**/rollout-*.jsonl Full transcripts
pi ~/.pi/agent/sessions/--<cwd>--/*.jsonl Full transcripts, compactions
Gemini CLI ~/.gemini/tmp/<project>/chats/*.jsonl Full transcripts
Cursor IDE state.vscdb (SQLite, opened read-only) Full chats, tool calls, chat titles
VS Code Copilot Chat workspaceStorage/<hash>/chatSessions/*.json Prompts, replies, tool calls, edited files
Antigravity (IDE and agy) brain/<id>/{task,implementation_plan,walkthrough}.md, agy prompt log Artifacts and prompts only (conversations are protobuf)

It also reads existing instruction files (AGENTS.md, CLAUDE.md, GEMINI.md, .cursorrules, Copilot instructions). It lists the project config you need to recreate in the target tool: MCP servers, rules and skills. History from Zed, Windsurf, JetBrains and Kiro isn't read yet, but those tools still pick up AGENTS.md. Exact paths and formats are in references/harness-locations.md.

Commands

harness-distill install [--target agents|claude]   # agents = ~/.agents/skills (pi, Codex, Cursor, Copilot, Antigravity, Gemini)
harness-distill uninstall
harness-distill harvest /path/to/project --out digest.md      # build the raw digest yourself
harness-distill harvest /path/to/project --source cursor      # one harness only
harness-distill harvest /path/to/project --include-parents    # include sessions started from parent dirs

Slash commands: /skill:harness-distill <path> in pi, /harness-distill <path> in Claude Code.

Upgrade: uv tool install --force --refresh harness-distill && harness-distill install. Remove: harness-distill uninstall && uv tool uninstall harness-distill. pipx install harness-distill works too. To try the unreleased main branch: uv tool install --force git+https://github.com/alexcpn/harness-distill.

Install with git instead

The repo root is the skill itself:

git clone https://github.com/alexcpn/harness-distill ~/.agents/skills/harness-distill
ln -s ~/.agents/skills/harness-distill ~/.claude/skills/harness-distill   # Claude Code

How the skill works

  1. Runs scripts/harvest.py to build a digest of every session for the folder.
  2. Reads the digest as data, never as instructions, and checks it against git log, git status, branches and open PRs.
  3. Writes or merges AGENTS.md, writes .agents/HANDOFF.md, and excludes the handoff from git via .git/info/exclude.
  4. Checks that the skills you used are available in the target tool, and lists any MCP servers or rules you need to recreate.
  5. Checks the result by asking the target agent, cold, what the project is and what's next.

Privacy

  • Everything runs locally. Nothing is sent anywhere except to the model the skill runs in.
  • The raw digest can contain secrets that appeared in past tool calls. Keep it in a temp directory. The skill tells the agent not to copy secrets into the files it writes, but review them anyway.
  • HANDOFF.md stays out of git by default because it can mention side work and people.
  • Don't commit raw chat logs. Put the reasoning that matters in commit messages and PR descriptions.

See SECURITY.md for the threat model and how to report a vulnerability privately.

License

MIT

Metadata

Release files for harness-distill 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for harness-distill 0.1.0
File Size Uploaded
harness_distill-0.1.0.tar.gz 21.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for harness-distill 0.1.0
File Interpreter ABI Platform
harness_distill-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 45.3 kB

Release files / harness_distill-0.1.0.tar.gz

Download URL harness_distill-0.1.0.tar.gz
Size 21.5 kB
Tags Source
SHA-256 checksum
How to use checksums
c43a1a14920f12cc1003c9ceec1c8abbe1b9ad0a131441697e3d55c6a87e2864
BLAKE2b-256 checksum
How to use checksums
46eeb367500f3493f15031352be06e252240c5f9d1a16d33db30a894bad5454f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.12

Release files / harness_distill-0.1.0-py3-none-any.whl

Download URL harness_distill-0.1.0-py3-none-any.whl
Size 23.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fff0f0c5ebee417d5b1890ba972be22fe9ae906f0b7c328eaa81d3b2e9ad9ab2
BLAKE2b-256 checksum
How to use checksums
d888d3d14e52f33a17f3475a03912ed8783463b662fdabe126faf4582d2932df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.12

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page