Why I built Framein
One local work frame across Claude, Codex, and Gemini.
The mess that started it
I do most of my coding through terminal agents now — Claude Code, Codex, and Gemini CLI, side by side in VS Code. Not because I'm chasing some "multi-agent" dream. It's more boring than that:
- Claude is my default for implementation.
- When something needs an outside opinion — a security hole, a regression, a plan that smells off — Codex catches things Claude doesn't.
- Gemini explains the result more clearly when I need to hand it to someone else.
- And honestly, sometimes I just hit a usage limit on one and switch to keep working.
So I had three terminals open, and I was the integration layer between them. Every switch meant re-explaining the same thing: here's the goal, here's what we must not break, here's what the last model already tried and why it failed. I was copy-pasting chat summaries between models like a human clipboard.
The worst part wasn't the typing. It was that the work kept dying at the boundary. The moment I switched models, the context — the actual contract, the failed attempts, the decisions, the validation state — was gone. Each model started clean and confident, and I started over.
I almost didn't build it
When I finally sat down to design this, I did what you're supposed to do: I checked if it already existed. It did. A lot.
CCB, Claude Squad, CC Switch, SuperClaude and its growing family, gstack, Matt Pocock's skill packs — the space was crowded. My first reaction was relief turning into deflation: lots of people clearly felt this exact pain, and several had already shipped. The honest read was that a generic "multi-CLI manager" would just get the comment every one of these gets: "How is this different from CCB?"
That question turned out to be the most useful thing that happened. Because once I stopped trying to build a CLI manager, I could see what was actually missing.
The insight: don't build a better handoff. Delete the handoff.
Every existing tool I looked at — and my own first design — solved the switching problem by making a better handoff package: bundle up a summary, a diff, the test results, and pass it to the next model. I was about to build the same thing.
Then it clicked that the handoff itself was the bug.
If three agents read from one shared source of truth — the task contract, the decision trail (ADRs), the validation results, the risk state — then "handing off" isn't a step anymore. The next model doesn't get my summary of the facts. It reads the facts. Nobody has to remember to pass anything, because nothing was ever separated.
That reframing is the whole product. Framein isn't a cockpit that runs three agents in a grid. It's a thin local layer that keeps one work frame under whatever agent you're already using, so the work survives longer than any single model or session.
What it actually does
The loop is four verbs:
start -> turn the request into a task contract before the work drifts
challenge -> ask a different model for a bounded objection when it's worth it
capsule -> prepare the next lead from facts: contract, diff, validation, ADRs, ledger
ship -> close with real build/test/risk gates, not the model saying "done"
You call them from the terminal, or as /fr:* slash commands inside Claude/Gemini, or as $fr-* skills in Codex. Same engine underneath, same local state. Your existing skill packs and personas stay exactly as they are — Framein just supplies the contract, ledger, and gates beneath them.
The decisions I'm most sure about
Compliance-first, or don't ship at all. Early in 2026 Anthropic clarified its terms and started blocking third-party tools that routed subscription traffic or pooled credentials. That isn't a hoop to jump through; it's a design boundary I agree with. So Framein collects no credentials, relays no tokens, pools no subscriptions, and never screen-scrapes terminal I/O. It calls the official CLIs locally when you ask it to, and they keep their own auth. The README's trust boundary isn't marketing — it's the line that decides whether a tool like this deserves to exist.
Decisions are append-only. ADRs can't be edited or deleted, only superseded. A decision trail you can quietly rewrite is worthless the moment a second model — or a second person — relies on it.
Zero runtime dependencies. The whole thing runs on Node 22's built-in node:sqlite and built-in test runner. No native builds, no dependency churn to break installs six months from now. The store is a local SQLite cache; the canonical snapshot is git-friendly JSON.
One writer at a time. The hard problem in shared agent memory isn't sharing — it's two agents writing inconsistent facts about the same thing. I started with the boring, safe answer: an atomic write lock with a TTL. Correctness before cleverness.
Where it is now
Pre-release, v0.0.4. The core — store, managed-block projection across CLAUDE.md / AGENTS.md / GEMINI.md, the task contract, the verify/risk/ship gates, the /fr:* and $fr-* wrappers, and the MCP server — is implemented and covered by 240+ tests.
The executable release path is now real enough to test: GitHub Actions builds Windows, Linux, macOS ARM, and macOS Intel artifacts; the macOS ARM and Intel artifacts pass Developer ID signing and notarization in CI. Still being hardened: Windows Authenticode through SignPath, clean-machine install checks, multi-developer workflows, and the public npm release.
I'm not claiming it'll change how you work. I built it because three terminals and a human clipboard was a bad way to spend my days, and the fix turned out to be small and local rather than big and clever. If you live in more than one coding agent, I'd like to know whether it helps you too.
It's MIT, built at Frameout. The name is a film term: frameout is when a subject leaves the frame and lives only in the imagined off-screen space. Framein is bringing it back in — pulling three scattered agents into one frame you can actually see.
— Ku Jaho, AX Center, Frameout
— Repo and docs: framein.dev
