crisgth Book a build call
I built a studio Claude can drive

InterStudio · build log

I got tired of losing AI assets in my downloads folder, so I built a studio

InterStudio is a Mac app that puts image, video and voice generation in one window, keeps every asset in a library you can actually search, and lets Claude drive it while I watch. That last part started as an accident.

Cris · 9 August 2026 · 9 minutes

Platform
macOS desktop
Stack
Electron · React · SQLite
Models
nano-banana · Veo 3.1 · Gemini TTS · Sonic
Runs
747 since April
Driven by
keyboard, CLI, or Claude

The mess I was actually solving

Producing a campaign in March looked like this. Four browser tabs open: one for images, one for video, one for text-to-speech, one for whatever model somebody had posted about that week. Four logins. Four credit balances. Four opinions about what "16:9" means.

Everything landed in ~/Downloads. By Friday I had output.png, output (1).png, output (4).png, and no memory of which prompt made the good one. When a client asked for "that dusk van shot, but vertical", the honest answer was that I'd have to build it again from nothing, because the prompt that produced it was in a tab I closed on Tuesday.

That's the actual problem. Not the generating. Generating is the easy part now. It's everything wrapped around it: where the file went, what made it, which campaign it belongs to, and how it reaches the person who asked.

So I built the thing I wanted.

One window

InterStudio is a desktop app. Electron, React, and a SQLite database sitting in ~/.interstudio. Nothing runs in the cloud except the model calls themselves, and those go straight from my machine to the provider with my own API keys.

The InterStudio Generate view: story tabs across the top, a filled prompt on the left, model settings on the right, and a sidebar listing live jobs.
Generate. Story tabs across the top, the prompt at the centre, everything the model can be told down the right, live jobs in the sidebar.

The thing that changed my week most is the least clever feature: story tabs. Each tab is one piece of work — a campaign, a client, an idea I'm chasing. It holds its own prompt, its own settings, its own reference images, and its own scratch notes, and it survives quitting the app. I stopped losing context between jobs because the context stopped living in my head.

Down the right side is everything the model can be told: provider, quality, ten aspect ratios, up to four reference images, and a multiplier if I want two or four variations instead of one. ⌘↩ starts it. The left sidebar fills with live jobs and their progress, so I can queue three things and go read something else.

Every generation gets a campaign tag and a job name. If I leave the name blank the app writes one for me from the prompt. That sounds trivial. It's the reason I can find anything six weeks later.

The library is the point

The gallery: a masonry grid of generated images, videos and audio cards with model and status filters above.
Every asset the app has made, filterable by model, status and campaign. Every thumbnail here is a real generation, pulled straight out of the library.

Every asset the app has ever made is here, tagged by campaign, filterable by model and status, searchable by prompt text. Videos play on hover with sound. Audio plays inline. I can drag any thumbnail straight into Finder, or into a Keynote deck, without opening a download dialog.

Click one and you get everything the app remembers about it.

Asset detail view showing the full prompt, model, provider, quality, aspect ratio, campaign tag, and a delivery checklist.
The prompt travels with the asset, along with where it has already been delivered.

The prompt lives with the asset, permanently. So "that dusk van shot, but vertical" is now a ten-second job instead of a re-invention: open it, read the prompt, change the aspect ratio, generate. And when a still is good enough to move, right-clicking it offers Create Video from This, which drops the image and its prompt into the video form already filled in.

That one right-click is most of my b-roll workflow.

What's actually in there

Four months of one account's work, filtered three ways. Same window, same library, same search box.

Gallery filtered to the brand-system campaign: a dense grid of 3D glass shields, crystal shards, chrome ribbons and liquid abstracts.
brand-system — glass, crystal, chrome, ink.

The brand set. Glass, crystal, chrome, ink. These are the ones that made me stop treating image models as a toy — I can hold a look across forty renders now, which is the part that actually matters when you're dressing a deck or a landing page.

Gallery filtered to field-crew: cinematic dusk photography of branded service vans and trades workers.
field-crew — every van at blue hour, none of them real.

The location set. Every one of these is a service van at blue hour that does not exist, parked outside a house that does not exist. Shooting this for real is a day, a crew, a permit and a golden hour you don't control. This was an afternoon of prompts.

Gallery with no campaign filter, showing portraits, mascot frames, editorial illustration, explainer graphics and landscape b-roll side by side.
No filter — five house styles in one grid, separated by a tag.

And this is the one I'd point at if you only looked at a single screenshot. Headshots, a mascot with a headset, risograph editorial, soft explainer diagrams, landscape b-roll — five house styles that would normally mean five freelancers, sitting in one grid, separated by nothing but a tag.

Three kinds of output, one set of habits

Two forms side by side: the Veo 3.1 video form with duration and source image controls, and the Cartesia Sonic speech form with voice, emotion, speed and volume.
Video and speech use the same shape of form as images — same tags, same library, same keyboard.

Images run through google/nano-banana, either via Replicate or OpenRouter depending on which is behaving that day. Video is Veo 3.1 — four or eight seconds, optionally animating a still I already made. Speech runs through either Gemini's TTS or Cartesia's Sonic, and Sonic is the one I use, because it takes an emotion, a speed, a volume, and inline SSML, so I can mark up a single line of voiceover to land the way I want it.

Different models, same form, same tags, same library. I don't context-switch between three products to make one ad.

Getting it to the person who asked

A Notion page holding the finished asset with its campaign, status and model properties, beside a Telegram chat where the app posted the same image.
The same render, posted to Notion and pushed to Telegram, without me touching either.

Finished assets can post themselves to a Notion page and ping a Telegram chat, and they save to a folder on disk on the way past. I paste a Notion URL into the form before I hit generate, and by the time the render is done the image is already on the page my collaborator is looking at, with the model and the timestamp attached.

The handoff stopped being a task. It's a field in a form.

The part I didn't plan for

Here's where it stopped being a nicer download folder.

InterStudio has a command-line entry point, and I built it because I wanted Claude Code to be able to make images for me. The obvious way to do that is a headless API: the agent calls a service, the service returns a URL, the agent hands me a link. I built that first. I hated it.

The reason is specific to creative work. When an agent generates in the background, I lose the seeing. I get a link to a finished thing and no sense of what was tried, no chance to say "stop, warmer" at second three. The judgment I'm actually paid for happens while I'm looking, and a headless pipeline removes the looking.

So I turned it around. The CLI doesn't generate anything. It writes a small request file, makes sure the app is running, and then waits. The app picks the request up, opens a new tab, fills the form in front of me, and runs it in full view — same jobs list, same progress, same gallery it would use if I'd typed it myself.

Claude running the InterStudio CLI in a terminal while the app opens a new tab, fills the form, and shows a badge reading Claude is generating.
One command from Claude. The app comes forward, opens a tab, fills the form, and runs it where I can see it.

A pill appears at the top of the window that says Claude is generating, and I watch the form populate with someone else's thinking. When it finishes, the CLI prints one line of JSON to stdout — job id, status, local path — so the agent knows exactly what it got and can keep working. Progress logs go to stderr, so the JSON stays clean.

Claude and I use the same app. Not the same API, the same window. If I don't like what it's doing I click into the tab and change the prompt, because it's just a tab.

What four months looks like

Statistics: 747 generations run, 97 percent finished on the first try, 123 days in service, four models across three providers, and a bar showing 678 images, 46 voiceovers and 23 videos.
Read from the app's local database on 9 August 2026. Counts, not estimates.

747 generations between 8 April and 9 August. 678 images, 46 voiceovers, 23 videos. 23 failures, which is about 3%. Failed jobs stay in the gallery with the error attached, so a bad run is something I can read rather than something that vanishes.

The number I care about most isn't on the chart: zero assets I couldn't find again.

Everything made in four months is one search away, with the prompt that made it attached.

What it actually changes if you make things for a living

Variants stop being expensive. Same prompt, four aspect ratios, four minutes. That used to be an afternoon, and a reason to say no to the client.

The brief and the output live in the same place, because the campaign tag goes in before the render rather than into a spreadsheet afterwards. Nobody waits on a handoff either — the asset posts itself to Notion and pings the chat while I'm still looking at it.

Your archive starts to compound. Six weeks of prompts is worth something. Six weeks of output (12).png is landfill.

You also pay providers directly, with no per-seat fee stacked on top of the model cost. That stops being a rounding error somewhere around the three hundredth generation.

And an assistant can work your tools without taking them off you. You keep the interface and the judgment; the agent gets another way to press the buttons.

Why I think this is the direction

Most of what's being built right now points at removing the human from the loop. Describe the outcome, get the artifact, never see the middle. For a lot of work that's fine. For creative work I think it's backwards, because the middle is where the work is. The middle is where you notice the light is wrong.

What I'd argue for instead is letting agents operate the real tools, in the open, at human speed, on the same library you already use. An agent that drives your app leaves a trail you can read: a tab, a prompt, a row in the gallery, a file on disk. An agent that calls an API leaves you a URL and a shrug.

I suspect a fair amount of software gets rebuilt this way, with a proper front door for agents that goes through the same interface as everything else rather than a chatbot bolted into the corner. Though I'll admit I might be generalising from one app and four months, and there's an obvious version of this that just becomes a slower way to do something a script could have done at 3am. The thing that keeps me on this side of it is how often I've watched a prompt fill itself in, changed one word, and run it again straight away — which I would not have done reading a results summary the next morning.

The honest limitations

It's a Mac app; the CLI leans on macOS specifics to bring the window forward. You bring your own API keys for Replicate, OpenRouter, Notion, Telegram and Cartesia, which means setup is a settings screen and not a signup. It's built for how I work, and I've made no attempt to generalise it. There's no installer page, no auto-update, no onboarding.

I built it for one person and it's been running every day for four months. That was the whole goal.

A note on the screenshots: the window chrome is a faithful rebuild of the app's interface rather than a raw screen capture, which is how the labels stay legible at this size. Everything inside it is real — every thumbnail is an actual generation exported from the library, and the usage statistics are read from the app's local SQLite database on 9 August 2026. Campaign tags have been shortened to keep client naming out of the post.