The Tool That Wrote This Post
How I built retell, a Claude Code plugin that turns AI conversations into blog posts. Starting from a 14 MB JSONL file with 0.6% signal.
What you’re reading right now was drafted by a Claude Code plugin called retell. retell is a pipeline that takes a raw AI conversation and turns it into a blog post. The conversation it’s drawing on? The one where I designed retell in the first place.
Yes, the tool is writing about its own creation. I’m aware that’s a little absurd.
But it works. And the fact that it works is kind of the whole point. So let me tell you how it happened. About three hours, starting with a question I hadn’t planned to ask.
It Started with a Question
I spend my entire working day inside Claude Code. Engineering, strategy, research, product thinking, writing. It’s become the environment where most of my real work happens. That means I accumulate a lot of conversations. Hundreds. Some are throwaway. Some contain genuine problem-solving that I think is worth sharing.
One morning, I found myself wondering something mundane: where does Claude Code actually store all these conversations?
The answer turned out to be more interesting than the question. Every conversation lives as a JSONL file under ~/.claude/projects/, named by UUID. I pulled up a specific session I’d been curious about. A 14 MB file containing 554 JSONL entries across five different project directories. It covered competitor research, a visual identity exploration with four parallel subagents running simultaneously, and a brainstorming skill that was itself built across multiple prior sessions.
554 entries. 14 megabytes. One conversation.
That’s when I stopped wondering where conversations are stored and started wondering what else you could do with them. I asked Claude to write me a technical planning document covering all the important details if I wanted to build a plugin that turns a conversation into a coherently readable blog post with a nice story arc.
Sixteen Bash commands later, I had a full spec: the JSONL data model, all six entry types, content block schemas, and a draft architecture for extracting narrative from noise. A complete blueprint for something that hadn’t existed ten minutes earlier.
But the blueprint had a flaw.
97.8% of Every Conversation Is Noise
I asked a simple follow-up: “How does this ensure that we treat context and token spend carefully without overflowing it?”
Claude’s response was refreshingly honest: “Good question. It doesn’t.”
The planning document had hand-waved the hardest problem. So we measured. Claude ran a full analysis against the actual 14 MB conversation file and came back with a number that reframed everything:
0.6% signal. 82 KB of narrative out of 13.8 MB.
The remaining 92% was tool_result blocks. Raw grep output, entire file contents, screenshot data. The kind of output that’s essential during a working session but meaningless in a story.
This single finding shaped the entire architecture. Here’s how retell handles it:
Stage 1: Parse. A deterministic Python script, not an LLM call. It strips the noise for zero tokens. No model invocation, no cost. The 13.8 MB file becomes roughly 90K tokens of actual signal.
Stage 2: Triage. A Sonnet-class model reads the cleaned signal and produces a structured assessment: blog-worthiness score, recommended angles with reasoning, a timeline of key beats. Cost: roughly $0.08.
Stage 3: Outline. Another Sonnet pass structures the chosen angle into sections, beats, quotes, and word count targets.
Stage 4: Draft. Opus writes the actual post. Voice quality matters here, so this is where the expensive model earns its keep.
Stage 5: Polish. A revision loop. The author reads, gives feedback, Opus revises. Repeat until done.
The model assignment is deliberate. Sonnet handles the gathering and structuring, the tasks where prose quality doesn’t matter. Opus handles the writing and orchestration, the tasks where it does. A typical run costs under $2, down from what would be $20+ if you naively fed the raw JSONL into a single prompt. The 0.6% finding didn’t just inform the architecture. It is the architecture.
Four Times I Said “Wait, There’s a Better Way”
With the token problem solved, the design started moving fast. But the original pipeline was fully autonomous. Conversation in, blog post out, no human in the loop. That was wrong, and I caught it almost immediately.
Interactive mode. “Some conversations make good stories. Some won’t. Is it possible to have this an interactive mode after the initial discovery, what story we want to tell?” The pipeline had assumed it knew what I wanted. It couldn’t. Some conversations have three good stories in them. Some have none. That’s an editorial judgment, not an algorithmic one. So the pipeline got two human gates: one after Triage to pick your angle, and one after Outline to approve the structure.
Opinionated recommendations. Having the Triage stage dump a cold list of five angles and say “you pick” wasn’t good enough either. The agent should have opinions. It should recommend the angle it thinks works best and explain why. Which arc has the strongest setup-conflict-resolution, which has the most quotable moments, which fits which audience. You can disagree. But the recommendation should be there.
Author context injection. This was the subtlest problem. I mentioned that the brainstorming skill referenced in the source conversation was itself something we’d built across multiple dedicated sessions. Claude’s response nailed it: “The agent only sees what’s in the JSONL. It has no idea that the brainstorming skill has its own origin story, or that a particular tool was custom-built, or that you had a specific motivation that wasn’t stated in the chat. That’s exactly the kind of context that turns a good blog post into a great one.” So the pipeline got a context injection step. After you pick your angle, it asks for backstory, audience, and anything the transcript can’t capture.
Zero-cost preview. Before spending even $0.08 on Triage, why not preview your recent conversations for free? A simple Python script reads filesystem metadata (file size, message count, subagent count, first and last user message) and shows you the last ten sessions at a glance. A $0 triage layer before the $0.08 Triage layer.
The Conversation Pushed Back
Not everything was additive. Some of the best moves were cuts.
I came back and laid down a hard constraint: no cross-conversation linking. Only the current conversation. Linking, except for subagents, is prohibited. Claude removed the feature cleanly, but then I noticed the explanation was muddled. One conversation doesn’t mean one blog post. The whole point of the Triage stage is that a single conversation can yield multiple angles, each becoming its own post. Different angle, different story. One conversation, many possible outputs. No cross-conversation parsing. That distinction mattered.
Then the model strategy. “Model choice is a real thing. I think we should use Sonnet for most of the gathering and Opus only as the orchestrator and writer.”
And in the same breath: “Narrative voice is always I. This is a tool for me.”
Two decisions in three sentences that locked the identity of everything retell produces. The first is economic. The second is personal. Every post that retell drafts is written from my perspective, because that’s the whole point. I lived it, now I’m telling it.
”What’s a Good Name for This?”
Toward the end of the session, I asked for a name. Claude offered a short list: retell, chronicle, recount. The recommendation was retell.
“Simple, accurate. You lived it, now you retell it.”
That landed. And we confirmed it should be a plugin, not a skill, because it needs Python scripts, multiple model stages, and interactive gates between them. The conversation was done.
And Now retell Wrote This
So here’s where the loop closes. This post was drafted by retell. The source material was the conversation I just described. The tool parsed its own origin story, triaged it for angles, recommended the recursion as the strongest hook, built an outline, and produced a draft. I reviewed it, gave feedback, and it revised.
The broader thing I keep thinking about: we all have these stories now. Anyone who works seriously with AI has sessions that contain genuine problem-solving, surprising discoveries, creative back-and-forth, real decisions made in real time. Most of it disappears. The conversation ends, you close the tab, and the only trace is a JSONL file you’ll never open again.
I wanted a way to surface the ones worth telling. To turn the working session into something others can read and take something from. retell is that mechanism.
The plugin lives at github.com/oborchers/fractional-cto. If you work with Claude Code and have sessions worth retelling, now you can.
Facing a complex problem? Before any code, a conversation. No pitch, no commitment.
Book a call