- TypeScript 96.7%
- CSS 1.6%
- JavaScript 1.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
ADR 0002 implemented (draft -> accepted). Every slide is composed against one fixed logical sheet (1024x800, one tunable constant) and uniformly projected into whatever shows it — transparency physics: the wobble scales with the ink, and rough strokes now regenerate only against the stable logical size, never on window resize. Stage, presenter tab, and replay render the identical sheet. When content outgrows the sheet the lamp pulls back: a discrete ~0.85 ladder grows the logical page until the content fits. Overflow is measured on the content box plus data-slide-overflow probes (the canvas's centered block column clips its own spill — the first screenshot pass showed clipped bullets and no pull-back), and a subtree observer remeasures on changes that land without a parent render — the async elk layout, found when the presenter tab measured pre-layout and stuck at zoom 1. The presenter tab also surfaced a real bug: a cloned stylesheet <link> never fetches in the about:blank tab under production builds (dev only worked because Vite injects inline styles) — the window now mirrors styles by serializing the opener's parsed CSSOM, verified against the prod build (ink-resolved strokes, Shantell in the popup). |
||
| .codex | ||
| .impeccable | ||
| .woodpecker | ||
| apps | ||
| docs | ||
| packages | ||
| skills/lazysketch | ||
| .gitignore | ||
| .prettierignore | ||
| .prettierrc | ||
| CLAUDE.md | ||
| DESIGN.md | ||
| eslint.config.mjs | ||
| mise.toml | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| PRODUCT.md | ||
| README.md | ||
| renovate.json | ||
| Taskfile.yml | ||
| tsconfig.json | ||
| vitest.config.ts | ||
lazysketch
Slides sketched live off your voice. You talk; a small, fast LLM listens to your live transcript and draws the deck while you speak — hand-sketched diagrams, bullets, code blocks, the occasional rubber-duck stamp — on lamp-lit paper, like an overhead projector that grew an opinion.
Try it: https://lazysketch.mortenolsen.pro
The agent drew this one itself, live, off a scripted run of exactly the talk you'd expect — duck requested by voice.
Fair warning: this is a quirky side project built for the wow effect of a deck drawing itself mid-talk. If you want AI to help you make actual presentations, there is real software for that. If you want to say "watch this" and then just… talk — welcome.
What you need
- A Chromium-ish browser (Chrome/Edge/Firefox). Speech models (Whisper for ears, Kokoro for a voice) run on-device in workers — a laptop with WebGPU makes them happy.
- An OpenAI-compatible endpoint of your own (OpenAI, Groq, Ollama, a LiteLLM proxy, …). Nothing is baked in; your key never leaves the browser except to the endpoint you name. A Haiku-class model is the sweet spot — small and fast beats big and slow here.
Everything is client-side: no backend, no account, your presentations live in your browser (IndexedDB), with export/import if you want to move them.
Quick start
- Open the app → Settings → set base URL + model (+ key), hit Save & preload models.
- Start a fresh sheet, paste in a talk outline as a cue file — it helps the model far more than you'd expect.
- Go live, open the mic, and start talking. The deck follows. When you stop, the session is recorded — replay it, scrub it, or resume for Q&A.
No mic handy? Rehearse from a script feeds prepared text through the exact same pipeline, at reading pace or as fast as the agent can draw.
On stage for real
Everyone who presents knows the moment: you're tired, under-rehearsed, you've delivered your points out of order, and the script in front of you has stopped being true. Reading it back doesn't help — what you need is someone who heard what you actually said and can tell you where to go from here. That's the prompter.
- Present opens the slides alone in a clean tab — move it to the projector, double-click for fullscreen. Your original tab keeps the tray, transcript, and gauges: that's your console now.
- Write the talk in the Script section on the desk — full prose or just your talking points — then flip on the Prompter next to Go live. A second loop listens along and keeps the next thing to say written large on your console, streaming in as you speak. On script, it's your own words. Off script, it's a live rewrite from where you actually are: points you've already made are dropped, the ones you haven't are lined up in an order that repairs the talk.
- So when you're lost: take a breath. The line is already there. Say it, and you're back.
- Audience question? It proposes a short answer. Wandered into a story? It holds the bridge home. Timing notes in the script are read, not parsed — it reasons about your pace against the clock.
- The prompter can run on a cheaper, faster model than the artist (Settings), Rehearse runs with it on so you can audition it before trusting it with a real room — and Replay shows its console alongside the talk afterwards, so you can judge every line it offered.
The CLI (optional, unpublished)
There's a lazysketch CLI so a coding agent (or you) can prime presentations from the
terminal: author the sheet and cue files as plain files, sync them into the browser, run
a scripted test session there — using the browser's LLM settings, credentials never
touch the CLI — and get an eval report of what the agent drew.
It isn't on a registry yet, so it's clone-and-link:
git clone https://code.olsen.cloud/incubator/lazysketch.git && cd lazysketch
mise install # Node 24 + task (or bring your own)
task install && task build
cd apps/cli && pnpm link --global
lazysketch --help
Then in the app: Settings → CLI access → Enable, run the pairing command it shows
you once, and you're connected (lazysketch status). The loop is
init/pull → edit files → push → run --script talk.txt → report → open --replay.
Agents can learn it from the skill in skills/lazysketch.
(Safari blocks the localhost bridge; use Chrome or Firefox for this part.)
Honest small print
- Latency is the whole game: with a good endpoint the deck trails you by a few seconds (there's a lag gauge — grease pencil, of course). With a slow model it trails you by an awkward silence.
- The agent sometimes draws the wrong thing, rewrites a block five times, or celebrates prematurely with confetti. This is considered part of the charm.
- The prompter follows meaning, not words — in testing it rode out a cat-on-the-keyboard digression without flinching — but it proposes, you decide. It's a prompter, not a co-author. Occasionally it re-offers the line you're mid-way through saying; it catches up on your next breath.
- Curious how it works? docs/design.md covers the transcript pipeline, the event-sourced deck, and the CLI bridge; DESIGN.md is the paper-world design system.
