Skip to content

Dev mode

liebstoeckel dev serves a deck with hot reload and a dev shell: your deck on the right, a sidebar on the left with the slide list, the annotation tools, and the agent’s status. Its first tool is annotations: draw on a slide, drop comments, and send the batch to an AI agent that edits your slide source directly. The deck hot-reloads with the result seconds later, and one click reverts a batch you don’t like.

Your deck files stay ordinary MDX/TSX throughout: the agent writes the same code you would, and nothing about dev mode appears in built decks.

Dev mode ships with the CLI. liebstoeckel dev works in any install of @liebstoeckel/cli; the machinery is its own package, @liebstoeckel/dev-server, which the CLI depends on, so there is nothing extra to install. You only reach for the package directly when you want to embed the dev server in your own tooling (it exports startDevServer).

  1. Start the server from your deck:

    Terminal window
    liebstoeckel dev

    Open the printed URL. The sidebar lists your slides, and its header names what the agent is doing: agent polling (waiting for work), agent working (it holds a batch), agent offline (nobody is listening), or server stopped, waiting while the page waits for a restarted dev to come back, after which it reloads itself. Click a slide to jump to it; the chevron collapses the sidebar to a thin rail so the deck gets the full width, and on narrow windows it floats over the deck instead of pushing it.

  2. In a terminal, have your agent enter the loop (the bundled agent skill knows this flow):

    Terminal window
    liebstoeckel dev poll
  3. In the browser: hit Draw or Comment in the sidebar, mark up the slide (Escape leaves the mode), Save (or Clear to drop the marks), then Send to agent.

  4. The agent receives the batch (comments, strokes, an annotated screenshot, and the resolved slide source file), edits the slide, and replies. Hot reload shows the change; the sidebar shows what was applied. Decks scaffolded with the current main.tsx shape keep their position: only the edited slide re-renders, and the current slide and step survive the edit.

  5. Not what you wanted? Revert puts the deck’s source files back exactly as they were when that batch was dispatched (every text source is snapshotted, so shared components and the entry are covered too; a file the agent created is removed, but anything you add after the agent replied is yours and stays), and your annotations reopen for another round. If a file cannot be restored (locked by an editor, say), nothing is marked reverted; free the file and revert again. A file that has since become a symlink pointing outside the deck is left alone rather than written through. If the agent replied with an error instead, the batch stays revertable, so a half-applied attempt can be undone the same way. Revert always undoes the most recent batch (or the last one the agent failed on); press it again to walk further back. Because the sources go back to before that batch, every batch applied after it is undone too, and those annotations reopen as well. While a batch is with the agent its annotations are locked and Send and Revert wait (a restore mid-edit would wipe the agent’s work, and a new snapshot would capture it half done); all come back the moment it replies. Send also waits while a batch is staged with no agent listening yet: one batch in flight at a time, so that every snapshot really is the state before its own batch. The last ten batches stay revertable; older snapshots are pruned (git covers anything beyond that).

Hover between two slides in the sidebar’s list (or below the last one) and press the + that appears. Describe the slide in one line (“a pie chart of cat breeds with one takeaway”) and Add. It shows as a pending row at that position, and the + below it lets you queue the next one right after it, so you can lay out several new slides before anything is sent. Send to agent dispatches them with your other annotations. The agent writes the slide file in your deck’s style, registers it in the entry at that position, and the sidebar jumps to it when it lands. Not right? Revert removes the file and the registration again.

Each annotation carries the slide index and its resolved source file, your comments with the element under each comment as a hint, your strokes, and a screenshot of the slide with the marks baked in. Positions are fractions of the slide itself, so they mean the same thing whatever the window size or sidebar state. Comments read as design direction (“make this heading calmer”); strokes read by shape: a loop means this thing, an arrow means direction or movement, a cross means remove.

  • Dev-mode state lives in .liebstoeckel/dev/ inside the deck (annotations, screenshots, revert snapshots, the session token). It is git-ignored.
  • An annotation you no longer want can be dismissed with the ✕ on its row; one that is currently with the agent is locked until it replies.
  • On start, dev applies any pending scaffold migrations for decks created under older conventions, one notice per patched file. The first run on an older deck adds the inert loader <script> tag to index.html (it only activates while dev is serving, and build strips it, so built decks ship byte-identical to before) and, for pre-dev-mode decks, upgrades the entry to the state-preserving hot-reload pattern.
  • The dev API binds 127.0.0.1 by default and every mutating request needs the per-session token; pass --host 0.0.0.0 only on networks you trust. Requests whose Host header is not localhost, a loopback address, or the bound hostname are refused, so a web page cannot reach the server by pointing its own domain at your machine (binding 0.0.0.0 lifts that check, since you are reaching it by a LAN address then). The deck itself is served under a path that includes the session token; /deck is a checked redirect to it, so the address bar shows the token path once you open the plain deck.

Comments

liebstoeckel

Code-first presentations your agent can author. One file out, no server.

© 2026 Leon Kaucher