← Articles Harupa
2026-07-22RU EN UA BY PL

From canvas to studio: a reusable library, parallel runs and auto-packaged clips

In the previous part I showed the canvas — the graph where a single clip gets assembled. Since then it's picked up a name, Vini Studio, and, more importantly, it stopped being just a graph. It became a workspace. Not a timeline like CapCut or Premiere, where you drag clips along a track and live inside the timeline. A canvas, where the whole idea fits at once and where you can lay out both your thoughts and your resources.

I took apart the canvas itself in part four, and working with elements in part five. Here it's about what I added as an architect to turn a one-clip pipeline into a studio where clips come out in batches.

The library: favorites always on top

Elements — characters, objects, locations — used to live as "souls" and references. Now it's a proper library: every element has a description and characteristics, and I keep my favorites bookmarked so they're always on top. No more fishing the hero I need out of the common pile every time.

But the more interesting part is under the hood. My library and my render cache are the same thing. Underneath there's a single artifacts table, and every artifact carries a signature: a hash of the model, the prompt, the set of references and the parameters. When a node is about to generate something, it first checks — is there already an artifact with this signature? If yes, we take the ready one, zero dollars. If no, we generate and write a new row. And "pick from the library" is exactly that same query, only by hand instead of automatically. One mechanism covers two jobs: don't pay twice for the same thing, and reuse what you've already made. I talked about the free re-run back in part four — this is its other half, turned to face the user.

And the element descriptions aren't there for looks. They go to two places at once: to the reference generator, so the picture comes out right, and to the scriptwriter, so it doesn't put a cabbage hat on the sheriff — I covered that bug in detail in part four. Before, when I was prepping a script, I dragged the character descriptions between tabs by hand. Now the element carries its own reference sheet, and everything fits together without copy-paste.

The prompt manager: system and personal

A prompt is also an artifact, and it's silly to write one from scratch every time. So a prompt manager appeared, and it has two levels. There are system prompts — they live in files as the source of truth and are available to everyone. And there are my personal ones, which I accumulate across projects and reuse.

Sounds mundane, but the feel of a tool rather than a toy comes together out of exactly these little things. No more running around, spinning in circles and typing the same text for the hundredth time — open it, paste it, go.

Recapping the previous episode: a memory node

I like giving the model context from previous episodes — that way the story doesn't break between clips. But the full script of the previous episode is huge, you can't paste it in whole: you'd eat the entire context budget at once, and the model would drown in the details.

So I made a separate node. I feed it the whole script text and ask: make a short recap, keep it to about a thousand tokens. It returns a compressed summary — that's what I pass on into the context of the next episode. It's essentially context compression, dressed up as a node. And for me it's a familiar architectural problem: no long-lived system can carry everything with it, it keeps a compressed state and works with that.

Parallel runs: I want to create, not wait

I want to create and I don't want to wait. When there are six scenes on the graph, each scene is an independent "image → video" chain. There's no reason to run them one after another. So I made the run parallel: you press once, and all the scenes go off to compute at the same time.

And this is where I caught a telling bug. The graph library the canvas is built on (litegraph, the same one under ComfyUI) can work out the execution order by itself. But on a graph with branching — one scriptwriter feeding six scenes — it would sometimes hand back an order that's topologically wrong: the third chain tried to start before the scriptwriter it depends on. A race condition out of nowhere.

I fixed it like this: I stopped trusting the order from the library and started building the schedule myself. Each node's promise is built by recursion over the real dependency edges — over who actually takes input from where. A node physically can't start until its inputs are ready, whatever the library might advise. After that, eight test runs out of eight are green; before the fix it was zero. Boring engineering, but it's exactly what lets you hit "run" and walk off to get coffee.

Subtitles: from what was actually said

A subtitles node appeared. It listens to the audio of the finished clip, finds the speech intervals and hands back SRT and VTT.

There's one non-obvious decision here: the subtitles aren't built from my script. The video model speaks its own way — not word for word, it paraphrases. If I'd burned my script into the frame, the subtitles would drift out of sync with the audio. So the node takes the real track of the final clip, runs it through whisper with timecodes, and assembles the subtitles from what was actually said. Then a translation pass, keeping the order of the lines. The output is SRT and VTT, aligned to fact, not to intent.

Packaging: a design system from a single prompt

Next comes packaging: hardsubs, outro, credits, lower-thirds. The whole wrapping of the clip.

Here's the funniest bit. I generated the design system for the packaging with a single prompt — I tossed the model "make me some design system", and it made some. And that "some" now runs the packaging. The node reads the design system — fonts, colors, gradients — plus those same VTT files, the model builds a plan of insertions (where and when to show a lower-third, with an anchor quote from the subtitle so the card lands exactly on the line), and Remotion renders it all in a headless Chrome: subtitles, wow-cards, chapter titles, outro. The render costs zero — it's local, you only pay for the plan, a couple of cents.

And an honest engineering story, without which the picture would be too glossy. The render node bit me. Remotion in a container with no memory limit grabbed half the host's RAM, and OOM killed it. And two thousand frames on a single render thread blew past the five-minute timeout. Cured it with a memory limit, a cache ceiling, three threads and a twenty-minute timeout — and pinned it down with constants in the tests, so it wouldn't quietly slide back. Ugly, but that's the difference between "works in the demo" and "works when you hit run at two in the morning".

A postcard, tags — and what it adds up to

On top, the nice little things. A stylized postcard with the characters — same principle: a system prompt plus elements, and out came a pretty thing. A description and tags for TikTok too, and the tags came out hilarious.

I don't consider myself a proper blogger, I run the channel on the side. But the numbers have moved: clips started reaching eight hundred impressions, and the previous episode gave 22% full watches — my personal record. What holds people is exactly these small touches I've listed here. And none of it took two hundred dollars or a million experiments. Twelve bucks a clip — that's the whole budget.

And the plan for the studio is to turn it into a real content factory. If you'd be into assembling clips in a system like this, or you're interested in working together — write to me under the video. If there's enough interest, we'll figure something out.