Making a Jotepad Tutorial with AI

TL;DR: A fully automated tutorial recording, with no human narration or manual interaction, using ElevenLabs for a Singapore accent. This article covers the issues faced and how we fixed them. Scroll down to view the final output and see Jotepad in action.

I wanted to try using an AI coding agent to make a product tutorial. It could operate the application, record the browser, write a script, generate narration, and assemble the video.

The product was Jotepad, a private workspace for ordinary Markdown notes in a folder you control. A connector on your computer gives an authorised browser access to that folder. Browser and connector communicate through a Relay using signed, end-to-end encrypted operations; the Relay cannot read the note content.

I started with a small request: show how to create a note and open it again. That became a full onboarding tutorial, with quite a few revisions along the way. Here is the final version, just under six minutes long.

The final tutorial, with generated narration and burned-in captions. The terminal views are controlled HTML panels showing the relevant commands; the Jotepad workflow runs against an isolated instance of the application.

The first full tutorial passed its automated checks, but watching it, I still found it difficult to follow.

Start with one note

The initial experiment was about a minute long. Playwright drove the browser through creating a note, editing it, switching to Preview, and reopening it from the Library. The workflow ran once as a validation pass before a slower recording pass, with visible typing, a synthetic cursor, and click indicators.

The first captions were too large. They were readable, but dominated the interface. I asked for smaller ones, and we settled on roughly 42-pixel text at 1080p, with a maximum of two lines.

The voice took more experimentation. We tried a temporary macOS system voice, OpenAI speech generation, and eventually ElevenLabs. One experiment with separately generated, instruction-directed audio kept changing accent and apparent speaker between sections. A continuous take improved consistency, but dropped a word. Independent transcription caught the omission.

The final approach used separate ElevenLabs clips with the same voice and settings, plus neighbouring text and request context to help continuity. Separate clips made it practical to replace a sentence without generating the whole narration again.

A passing video with seventeen seconds of silence

The first full tutorial ran for about five minutes. It decoded correctly, had no detected black sections, and had readable captions. The QA report passed.

But some gaps between narration sections lasted fourteen to seventeen seconds. The checks required a minimum pause so that sentences would not run into each other. They had no upper bound for unexplained silence. A seventeen-second gap therefore satisfied the rule perfectly.

There were also problems with what the tutorial taught. It began after browser authorisation, so it never showed a new user how to connect their first browser. Folders had names such as 10_Projects, and a normal human note included unnecessary front matter. Local Git commits appeared without enough explanation that backing up to GitHub required a separate push.

I asked to revise and validate the flow before producing another video. We used ordinary names such as Projects and AI Research, gave the human note plain Markdown, and rebuilt the tutorial around the actual setup steps.

Show the boundaries clearly

First-browser pairing was the biggest omission. The original production brief avoided recording login and sensitive setup information. For this product, though, pairing is an essential part of understanding how access works.

We used a disposable environment to show the real ceremony. The connector produces a short-lived six-digit code. The browser submits its request, and the user compares three matching words in the browser and terminal before explicitly approving it. Entering the code alone does not authorise the browser.

An early revision showed important terminal panels for about a second, barely enough to read them. Later versions held them for around nine or ten seconds and typed the pairing code slowly enough to observe.

The same care applied to the Git and AI workflow. Saving a note, making a local commit, and pushing to a remote are separate actions. Jotepad makes local commits; the GitHub push remains manual. An agent can work in the same notes folder, and an agent-maintained note is read-only in the Jotepad browser. That restriction does not make the Markdown file immutable on disk.

The tutorial explains the external Codex or Claude folder setup and the manual push through terminal-style panels. It does not sign into personal accounts or perform a real GitHub push.

I also asked for an architecture overview before the commands. A viewer needs to know what the browser, Relay, connector, and notes folder do before the setup details are useful.

Let the words determine when to click

After those changes, another issue remained: sometimes an action happened before the narration introduced it. By the time the voice said to choose a button, the recording had already moved to the next screen.

The earlier script grouped a whole topic into one narration block. Starting actions at the beginning ignored the seconds of explanation before an instruction.

The final tutorial used 27 short cues. Each covered one visible state or a small group of closely related actions. ElevenLabs returned character-level speech alignment, which let the scheduling script find the time of a particular phrase.

For example, the recorder could wait for “choose Request approval” before submitting the pairing form, or “choose Jolt Pad dark” before changing the theme. Those phrase timestamps became explicit markers in the recording schedule.

The production sequence became:

  1. Validate the workflow against the application.
  2. Write short narration cues for the visible steps.
  3. Generate and measure the audio.
  4. Derive action markers from the spoken phrases.
  5. Record the browser following that schedule.
  6. Assemble the video and check the result.

The recorder could now fail if a section overran its allocated time, and a premature click could be fixed by adjusting its phrase marker.

Adding Settings, Appearance, and Graph demonstrations brought the final version to nearly six minutes, with more room for explanations and readable screen holds.

Pronunciation is part of the source

Jotepad should be pronounced “Jolt Pad.” An earlier pronunciation hint was wrong, and I corrected it late in the process.

The captions, product name, and commands still needed to say Jotepad. Only the speech generator's input needed Jolt Pad.

Each cue stored both forms. We regenerated the eight affected clips and kept the existing start times because the new audio still fitted its slots. The other nineteen cues and the browser recording could stay in place.

The replacement clips had slightly different lengths, so we checked the gaps again. Keeping the source clips, timing data, captions, and scripts alongside the MP4 made this a manageable edit.

The result

Technical checks caught missing words and media problems. Reviewing the visible steps exposed the pacing and explanation issues. We turned those lessons into repository instructions and a reusable video-production skill, covering short cues, phrase timing, readable holds, and final review.

It took several rounds of feedback, but the recording, narration, and assembly were automated. I expected the result to feel much more artificial than it did.