AI summary

We used an AI deck generator for months and it never produced a deck we could send as-is. The problem was not the generation. It was that no hosted tool can reach the repo where our design system, our product screenshots and everything we know about a deal already live. So we built one that can.

A proposal deck for a dealer group used to take a day here, sometimes two. Very little of that was writing. It was hunting for the right product screenshot, correcting a layout the tool had already chosen for us, and dragging a slide back onto brand one box at a time.

We tried to fix that with Gamma. It did not work. The reason it did not work turned out to be more interesting than the tool.

What actually went wrong with the AI deck tools

Gamma generates well. That was never the complaint. The complaint is that it cannot see anything of ours. Not our design tokens, not our component library, not the 498 product screenshots and logos sitting in our monorepo. It works from a prompt and its own themes, so every deck came back needing the same hour of correction. That hour was the entire thing we were trying to save.

The integration was the second problem. When we first scoped a deck generator in February, the blocker was an API that looked write-only, with no way to point it at a template we had already approved. The fallback was to feed it long prose descriptions of each slide and hope. That is not a pipeline. That is dictation.

The third problem is the one nobody markets against, and it is the one that decided it. A deck made in a hosted tool is not in git. No diff, no branch, no review, no history. It also has no relationship to anything else the company knows. Our agents read the repo, and the repo is where we keep what we have learned: segment playbooks, lender integrations, state-by-state titling rules, forty-one deal folders of prior context, all of it sitting next to the code it describes. A deck built outside that starts from zero every single time, and it stays at zero, because nothing it produces comes back.

We had already learned this lesson somewhere else. A few months earlier we rebuilt ekho.com off Webflow in about a week, and the thing that made it work was not the model. It was moving the content into the repo and writing down what good looked like, so an agent could execute against a spec instead of guessing. Decks were the same shape of problem with a worse vendor fit.

Three days

The first version of the deck pipeline was built over the first three days of August and merged on the fourth. It has been rebuilt in pieces most weeks since. It now runs every deck we send.

The model never writes slide HTML. It fills tokens in slides a designer already approved. Everything else follows from that.

Each slide is a template folder in the repo with three files, and 97 of them ship today. The HTML carries named tokens, so COVER_HEADLINE and SECTION_TITLE are the only surface an agent touches. The rest of the file, the type scale, the grid, the spacing, the colours, is fixed. A metadata file next to it records what the slide is for, when to use it, which variants exist, and whether it needs real sourced data. That last flag is the guardrail that stops a testimonial slide shipping with an invented quote.

The slide template library in the Ekho deck composer, showing 97 templates filtered by slide type, product, frequency and whether they need sourced data
97 templates, faceted by what they are for. The "needs sourced data" filter marks the slides that cannot be filled from a prompt. Previews and descriptions blurred here.

Assets work the same way. One shared folder, 505 files, referenced by relative path from every deck. No per-deck copies, no base64, no remote URLs. Product mocks are organised by vehicle type, so a deal marked automotive gets automotive screenshots and cannot quietly ship a motorcycle. The asset picker enforces that at the moment of choosing rather than in a review comment afterwards.

The searchable image asset library in the deck composer, pre-filtered to automotive and vehicle-agnostic product mocks
Double-click any image on a slide and the picker opens beside it, already narrowed to the vehicle type on the deal. Thumbnails and descriptions blurred here.

What goes in

A deck starts from what we already have on the account. Granola notes and Gong recordings from every call so far. The deal record and company detail out of HubSpot. Whatever the rep pastes in.

Then a short set of choices, which decide the shape of the deck rather than its contents. Which sales motion this is, and what kind of call: an intro call, a discovery session, a proposal, and a deck sent as a handoff all open differently from one presented live. Then the archetype the account maps to, because a standalone rooftop, a dealer group, an OEM with a dealer network and a lender each want a different arc. Then which product leads, and what the account sells.

Those answers become a small YAML file in the deal folder, and the composer reads it to work out the spine of the deck: cover, problem, how it works, proof, commercials, rollout, close. The arc is a spine and not a slide list, which was the mistake in the first version. Every deck came out identical because the motion was a hardcoded sequence. Now the agent picks the slides this specific pitch needs from the whole library and writes copy for them, and two prospects do not get the same deck.

The ergonomics came from Plannotator

The thing that took longest to get right was not generation. It was the handoff.

An agent that composes a deck and then keeps going is useless, because the person who knows the account is not in the loop at the point where their knowledge matters. We took the shape of the answer from Plannotator, which we already use for plan and code review: the agent produces a draft, opens a local surface, and then blocks. The human marks it up. Structured feedback comes back in one piece. Nothing proceeds on the agent's own judgement.

So the deck pipeline stops. It composes a first pass, opens a composer in the browser, hands over the URL, and waits.

The first version of the review surface was a chat with the model on every slide, and it was wrong in a way worth naming. A transcript is not a review. You could not walk a deck end to end, drop twenty remarks, and hand the lot over, and nothing survived the session. It has been replaced by an annotation layer.

Click anything on a slide and a small menu appears over it: comment, label, or edit the field directly. Highlight three words and the remark points at those words rather than the paragraph. With something selected, any key you press opens the comment box carrying that keystroke, which turns out to matter more than it sounds: the cost of leaving a remark is now one click and typing.

The deck composer with two numbered review notes on the cover slide and the feedback log open on the right
A review in progress on a deck with no client on it. Each note paints a numbered bubble on the thing it is about, and the log on the right matches.

Half the review never needs a sentence. Ten preset labels sit behind a digit key: too much text, make it bigger, dead space, container should hug, wrong image, needs a source, wrong tone, wrong place, cut this, looks good. Each one carries an instruction into the export, so it reaches the agent as something to act on rather than as a mood. For anything that does need a sentence, a comment takes attachments, and an attached image can be drawn on with an arrow before it goes.

The label picker open over a selected headline, showing ten preset review labels each with a digit shortcut
The one-click half of a review. Select something, press a digit, move on.

A note anchors to the token path it was rendered from, not to a position on screen. So it still points at the right thing after the deck is regenerated, the slides are reordered, or the theme changes. When the reviewer is done, one button writes the whole pass, plus every annotated image, into the deal folder as markdown for the agent to read. A note is a request and not an edit, so nothing in the deck moves until someone moves it.

Everything you change by hand is pinned. A later rebuild from the agent will not overwrite a field you have touched, which sounds obvious and was not: the first version happily reverted an hour of somebody's edits. There is a version history now for the same reason.

Grid view of a 13-slide deck in the composer, showing every slide at once
Grid view. A deck should read as one object, which is easier to check when you can see all of it.

The deliverable is a single self-contained HTML file with every asset inlined, downloaded by the person who built the deck rather than by the agent. There is a PDF path too, which writes an archive copy and a second one sized to clear Gmail's 25 MB attachment limit, because a heavy attachment silently becomes a Drive link and that is not what a prospect should receive.

The export menu in the deck composer, offering an HTML download, a PDF, and copy-for-review options
What you leave with. The Notion and JSON options exist because a deck usually needs one more round of review before it goes out.

Everything is in git, including the deck

The composer is not the source of truth. Two files in the deal folder are: the YAML context and a JSON composition that records every slide and every token. Rebuild from those two and you get the identical deck back. That is what makes the deck a repo artefact rather than an export, and it is why a deck review is a pull request like anything else.

It also means a deck can borrow. When we write down what we learned on a call, the next deck for a similar account can use it, because both live in the same knowledge base. Roughly 84,000 lines of templates and tooling sit in that repo now, and a deck goes through the same review as the product it describes.

Prospect decks were the first use. Board decks came next, with their own twelve templates and a fixed shape we do not compose from scratch, because that shape was expensive to settle and rebuilding it re-earns every mistake. Then QBRs. Then the biweekly all-hands. Every deck the company makes now comes out of the same pipeline.

Sending one

A finished deck publishes to a link. A champion inside the account opens the same composer in a stripped-back mode, reads it, comments, and changes the wording or swaps an image where they disagree. When they submit, their remarks come back anchored to the tokens that produced them, so a comment survives a rebuild, a reorder and a theme change. The rep opens the deck the prospect saw with the markup on it and accepts or rejects each one.

That last part is the reason we built it. On an enterprise deal the champion has to sell this internally before anyone senior sees it, and a PDF gives them nothing to push back on. A deck they can mark up is a deck they co-own. The same storage runs an internal library behind SSO, so anyone here can read every deck the company has sent.

The general version of this

None of what we learned here is really about decks.

Generation is close to free now and getting cheaper. Context is not. The design system, the approved assets, the last four calls with this account, the reason a slide is shaped the way it is: a hosted tool can reach none of it, and it cannot write anything back either. So it hands you something plausible and generic, and a person spends an hour making it specific and correct.

The tools worth having are the ones that sit where your context already is. For us that meant the repo, because that is where the product, the knowledge base and the agents all live. Three days of work to get the first version standing was not a big bet. The library behind it is a year of accumulated judgement about what a good slide is, and that part was never something we could have bought.

If you build software this way and it appeals, we are hiring. If you want to see what the platform underneath actually does, start with the Transaction Engine or the AI Sales Agent.

Frequently asked questions

They generate well and they cannot see anything of ours. No design tokens, no component library, no product screenshot library, and no way to reference a template we had already approved. Every deck came back needing an hour of correction, which was the hour we were trying to save. The deeper problem is that a deck made in a hosted tool is not in git, so it has no diff, no review, and no connection to what the rest of the company knows.

No. It fills named tokens in slide templates a designer already approved. The HTML, the type scale, the grid, the spacing and the colours are fixed in the template. That is what makes the output consistent instead of plausible.

Meeting notes and call recordings from the account, the deal record out of HubSpot, and a short set of choices: the sales motion, the kind of call, the archetype the account maps to, which product leads, and what they sell. Those choices set the narrative arc. The agent then picks the slides that particular pitch needs and writes the copy for them.

Yes. Two files in the deal folder hold the whole thing: a YAML context and a JSON composition recording every slide and every token. Rebuild from those and you get the identical deck back, so reviewing a deck is a pull request like anything else.

By marking it up. Click anything on a slide to comment on it, or press a digit for one of ten preset labels such as "too much text" or "container should hug". A comment takes attachments, and an attached image can be drawn on. Each note anchors to the token that rendered the element, so it still points at the right thing after a rebuild or a reorder. One button hands the whole pass to the agent as markdown. A note is a request, not an edit, so nothing moves until someone moves it.

Yes. A published deck opens in a stripped-back version of the same composer. They can comment and change wording or swap an image, and their remarks come back anchored to the tokens that produced them, so a comment survives a rebuild or a reorder. Whoever owns the deal accepts or rejects each one.

Three days, merged on the fourth. It has been rebuilt in pieces most weeks since. The three days were never the hard part. The library of approved slides behind it is a year of accumulated judgement about what a good slide is.