Repository navigation
Kadal Deck 0.3.0
Minor Changes
-
1af5183: Commands: everything a person can do to a running deck is now a command in one registry —
deck.commands(andwindow.__deck.commands), with stable ids (nav.next,present.blackout,
draw.shape,deck.slide…), descriptions, and zod parameters exported as JSON Schema. The
keyboard runs through it, so a phone remote or an AI agent can do exactly what the keys and
buttons do. New commands aim the laser (present.laserAt), drive the pen from a touchpad
(draw.pen), mark a region (draw.shape: circle, box, underline, arrow), zoom to a point, and
read the deck (deck.state,deck.outline,deck.slide,deck.search). The manifest now
carries each slide's speaker notes as plain text (notesText).useCommandregisters your own. -
e960d13: Narration: rehearse with the deck reading its own notes. Each
[click]part of a slide's
<Notes>is spoken at its step, then the deck turns the page withnav.next— through the
command registry, so the presenter window, a projector and the room follow. A bar at the bottom
of the presenter view (and on the deck behind?narrate, or the newRkey) has prev / play /
next / stop, speed, mute and volume, voice and engine menus, "follow the narrator", and a
timeline with a mark per slide to seek. Every control is anarrate.*command.Three voices behind one interface, picked per segment: baked clips from the new
kadal-deck narrate(Kokoro-82M on the CPU, MP3/Opus via ffmpeg or WAV, indexed by SHA-256 in
public/narration.json), Kokoro-82M in the browser in a Web Worker (WebGPU fp32 or WebAssembly
q8, downloaded on the first play and cached), and the browser'sspeechSynthesis. Kokoro needs
kokoro-js, a new optional peer dependency (kadal-deck narrate --setupinstalls it); without it
nothing of it is built. Config:narration: { enabled, engine, voice, rate, gap, silent, model, dtype }; slide frontmattersay:andnarration: false. Licences of the pieces it reaches for,
including eSpeak NG (GPL-3.0-or-later) inside the phonemizer, are inTHIRD_PARTY_NOTICES.md. -
2473f77: Phone remote: the presenter view's new Phone remote button shows a QR, and the phone that
scans it becomes a one-handed remote at/<slug>/remote(RemotePagefrom
@kadal/deck/remote; addremote: RemotePageto<Deck pages>). It shows a live copy of the
current slide, rendered by the deck's own components. Touch the slide to aim the laser or the
spotlight, draw on it with the pen, or tap to zoom. Hold the air-pointer button and move the
phone to point (DeviceOrientation with iOS's permission prompt, or a Gyroscope where there is one,
smoothed by a One Euro filter). It also has next and back (or a swipe), blackout, focus labels, a
slide list, the notes for the current click step, the timer with pacing, buzzes at chosen
minutes, haptic ticks and a screen wake lock. Everything it does runs as a command in the
presenting window.With a room, the phone is a presenter socket holding the ticket from the QR's fragment. The
protocol gainscommand,command:result,remote:state,remote:kickandremote:bye, plus
validators. Without a room,kadal-deck devrelays it over the dev server's HMR socket with a
pairing code.kadal-deck dev --httpsserves a self-signed certificate so phones get motion
sensors. In the presenter view without a room, the laser now shows on the current slide, and the
remote's laser, ink and zoom reach the play window. -
71ad8e8: The presenter gate follows the host: when it says the deck has no passcode (
passcode: false) the
gate stops asking for one, and when it gives asignInURL it offers "Sign in as the author" —
on its own, or below the passcode field. Only http(s) links are followed. -
2d862df: Decks without a build.
@kadal/deck/runtimecompiles a deck from its text in the browser —
the same remark/rehype passes, Shiki highlighting, notes, magic move and glossary as the Vite
plugin (both now sharecompiler/pipeline.ts) — and returns diagnostics with lines instead of
throwing. The new@kadal/deck-shellpackage is one prebuilt static page that runs any
deck.mdxserved beside it, under any path; with?previewit is an editor's live iframe,
speaking a smallpostMessageprotocol (source in; diagnostics, outline, position, command
results and picked points out).<Deck base>sets the URL root explicitly. Slides compiled
this way use the engine's components and cannotimport.
Patch Changes
- ac41497: A deck compiled again in the same page (an editor's live preview) now shows the new slides: the
slide-module cache is keyed by each manifest entry's loader instead of the slide's index.
Packages
@kadal/deck@0.3.0@kadal/create-deck@0.3.0@kadal/deck-angular@0.3.0@kadal/deck-fresh@0.3.0@kadal/deck-preact@0.3.0@kadal/deck-python@0.3.0@kadal/deck-qwik@0.3.0@kadal/deck-solid@0.3.0@kadal/deck-svelte@0.3.0@kadal/deck-vue@0.3.0@kadal/deck-wasm@0.3.0
Published from release.yml through npm trusted publishing, with provenance.
npm create @kadal/deck@latest my-talk # a new deck
npm install @kadal/deck@0.3.0 # or upgrade one