@jokerized/decksmith 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +121 -4
- package/dist/cli.js +4101 -651
- package/dist/deck-runtime.js +70 -2
- package/dist/index.js +4134 -651
- package/dist/mcp.js +3642 -515
- package/dist/types/build/files.d.ts +13 -1
- package/dist/types/deck/motion.d.ts +64 -0
- package/dist/types/deck/playback.d.ts +206 -0
- package/dist/types/deck/repack.d.ts +10 -0
- package/dist/types/deck/runtime.d.ts +96 -1
- package/dist/types/deck/subtitles.d.ts +29 -1
- package/dist/types/emit/archetypes/annotated-figure.d.ts +1 -1
- package/dist/types/emit/archetypes/bar-compare.d.ts +0 -28
- package/dist/types/emit/archetypes/callout.d.ts +0 -5
- package/dist/types/emit/archetypes/claim-figure.d.ts +15 -0
- package/dist/types/emit/archetypes/grid.d.ts +0 -14
- package/dist/types/emit/archetypes/line-chart.d.ts +0 -8
- package/dist/types/emit/archetypes/pipeline.d.ts +15 -1
- package/dist/types/emit/archetypes/stack.d.ts +1 -1
- package/dist/types/emit/composition.d.ts +47 -2
- package/dist/types/emit/faces.d.ts +22 -0
- package/dist/types/emit/fit.d.ts +127 -0
- package/dist/types/emit/kit.d.ts +104 -2
- package/dist/types/emit/look.d.ts +138 -0
- package/dist/types/emit/motion.d.ts +244 -0
- package/dist/types/emit/svg.d.ts +54 -16
- package/dist/types/emit/theme.d.ts +1 -1
- package/dist/types/emit/themes/index.d.ts +19 -1
- package/dist/types/emit/themes/packs.d.ts +15 -0
- package/dist/types/emit/themes/pick.d.ts +104 -0
- package/dist/types/emit/type.d.ts +111 -0
- package/dist/types/index.d.ts +35 -1
- package/dist/types/plan/direct.d.ts +66 -0
- package/dist/types/prefs.d.ts +15 -1
- package/dist/types/source/fonts.d.ts +11 -1
- package/dist/types/types.d.ts +38 -0
- package/dist/types/verify/fidelity.d.ts +34 -0
- package/dist/types/verify/fill.d.ts +205 -0
- package/dist/types/verify/motion.d.ts +33 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -220,6 +220,49 @@ Arrow keys, Space and PageUp/PageDown step; clicking the left or right third doe
|
|
|
220
220
|
notes; `f` is fullscreen; `m` mutes the voice and `s` hides the subtitles. Every step is
|
|
221
221
|
deep-linkable (`#3` is slide 3, `#3.2` its second reveal).
|
|
222
222
|
|
|
223
|
+
### The v2 player (`--design v2`)
|
|
224
|
+
|
|
225
|
+
`build --design v2` (or `"design": "v2"` in the storyboard or config) gives `deck.html` the
|
|
226
|
+
v2 player; everything else about the build is unchanged. A deck that is already built
|
|
227
|
+
gets it without rebuilding:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
decksmith repack out/ # writes out/deck2.html beside deck.html, never over it
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
`repack` swaps the inlined runtime, marks the page and checks that every JSON island is
|
|
234
|
+
byte-identical — no Chrome, no TTS, no re-render.
|
|
235
|
+
|
|
236
|
+
- **One control bar**: play/pause, the counter, narration speed (0.75–2×), `CC`, caption
|
|
237
|
+
size (S/M/L/XL) and fullscreen — or, in a window too narrow for those beside a caption,
|
|
238
|
+
play and one settings menu. **It never covers text.** It docks under the slide in spare
|
|
239
|
+
letterbox (a portrait phone); over the slide's empty bottom padding when that holds a
|
|
240
|
+
40px target (a slide about 720px tall or more), where it hides 2.5s after the last
|
|
241
|
+
pointer move while the deck plays; otherwise in a band under the slide that it shares
|
|
242
|
+
side by side with the captions, whose text is padded in past the buttons.
|
|
243
|
+
`test/deck-page.test.ts` measures controls against caption text and against every glyph
|
|
244
|
+
the slide draws, at six viewports.
|
|
245
|
+
- **Play/pause** pauses the voice where it is and carries on from the same word. A deck
|
|
246
|
+
opens paused; stepping while paused moves the slide silently.
|
|
247
|
+
- **Speed** sets the narration's `playbackRate` live, on the sentence already playing, and
|
|
248
|
+
divides the reveal glides and every autoplay wait by the same factor so they keep pace.
|
|
249
|
+
A stop with no narration holds for its reveal and 1.5s at 1×, not the author's gap.
|
|
250
|
+
- **Captions** are sized from the slide (3% of its height, 13px floor; L and XL keep floors
|
|
251
|
+
of 16 and 19px so the size control works on a phone) and the slide gives up only one
|
|
252
|
+
two-line strip for them: 84% of the frame at 1080p, 83% in an 800×450 embed (v0.8.0: 77%
|
|
253
|
+
and 69%), 100% in a portrait letterbox. Long cues are cut to two lines of the strip's
|
|
254
|
+
actual width, which also splits Japanese and Chinese.
|
|
255
|
+
- **Keys:** Space steps forward (Space is the presenter's key, not play); `Enter` plays and
|
|
256
|
+
pauses; `c` (or `s`) captions; `<`/`>` speed; `+`/`-` caption size. Letter keys fall back
|
|
257
|
+
to the physical key under a Korean or Japanese IME. Anything held with Cmd, Ctrl or Alt
|
|
258
|
+
is left to the browser.
|
|
259
|
+
- **Preferences** — speed, captions on/off, size — come from `?speed=1.25&cc=0&ccsize=l`
|
|
260
|
+
(this visit only), else from `localStorage` (`decksmith.prefs.v1`), else the defaults.
|
|
261
|
+
When the viewer changes one, the deck posts
|
|
262
|
+
`{ type: "decksmith:prefs", speed, cc, ccsize }` to its parent so an embedding site can
|
|
263
|
+
keep it per user (a cross-site iframe's storage is partitioned), and it applies the same
|
|
264
|
+
message when the parent sends it. Check `event.origin` on your side.
|
|
265
|
+
|
|
223
266
|
Stepping forward *plays* the reveal rather than cutting to it — the step layer sweeps the
|
|
224
267
|
composition's timelines across frames instead of seeking once. Backward steps, `Home`/`End`
|
|
225
268
|
and deep links cut, because entrance tweens run in reverse look like elements un-drawing
|
|
@@ -784,8 +827,11 @@ invalidates a storyboard you have already edited.
|
|
|
784
827
|
| `lang` | the source's | plan | BCP-47. Drives the copy, the voice, and the font subset |
|
|
785
828
|
| `tone` | `plain` | plan | `plain` · `academic` · `conversational` · `punchy` |
|
|
786
829
|
| `density` | `normal` | plan | `sparse` · `normal` · `dense` — how much text a slide may carry |
|
|
787
|
-
| `theme` | `ink` | emit | `ink` · `paper` · `mono
|
|
830
|
+
| `theme` | `ink` | emit | `ink` · `paper` · `mono`, or a v2 style pack by name (see Themes) |
|
|
831
|
+
| `design` | `classic` | narrate, emit | `classic` is the v0.8.0 look byte for byte · `v2` is the redesign: the v2 player (see "The v2 player") and a style pack per deck when no theme is named |
|
|
832
|
+
| `packSeed` | the source id | narrate, emit | what `design: v2` hashes to pick a pack; pass a paper id so its languages share one |
|
|
788
833
|
| `animationSpeed` | `1` | emit | multiplies every duration, hold and beat length. Below 1 is faster |
|
|
834
|
+
| `design` | `classic` | emit | `classic` (the 0.8 look, byte-identical) · `v2` (the redesign — see [v2 motion](#v2-motion)) |
|
|
789
835
|
| `narration.voice` | picked for `lang`+`tone` | narrate | an explicit edge-tts voice id |
|
|
790
836
|
| `narration.rate` | `+0%` | narrate | edge-tts prosody |
|
|
791
837
|
| `narration.pitch` | `+0Hz` | narrate | edge-tts prosody |
|
|
@@ -832,8 +878,8 @@ why `slideCount` did nothing.
|
|
|
832
878
|
decksmith.config.json: unknown preference "narration.speed". Valid: enabled, voice, rate, pitch, subtitles.
|
|
833
879
|
```
|
|
834
880
|
|
|
835
|
-
On the command line: `--slides --lang --tone --density` on `plan`, `--theme --
|
|
836
|
-
`build
|
|
881
|
+
On the command line: `--slides --lang --tone --density` on `plan`, `--theme --design
|
|
882
|
+
--pack-seed --speed` on `build` (`--design --pack-seed` on `narrate` too), `--voice --rate --pitch --no-subtitles` on `narrate`, `--images --image-provider
|
|
837
883
|
--image-model --image-style --image-max` on `plan` and `illustrate`, and all but the image
|
|
838
884
|
flags on `pack`, which records the preferences the deck was made under — whether it was
|
|
839
885
|
illustrated is read off the storyboard itself, the way `narration.enabled` is read off the
|
|
@@ -841,9 +887,43 @@ narration beside it.
|
|
|
841
887
|
|
|
842
888
|
A preference sitting at its default says nothing, so a stored artifact wins over it and
|
|
843
889
|
loses to anything you type. `plan` stamps `lang` and `theme` into the storyboard it
|
|
844
|
-
writes; `build` then uses the storyboard's
|
|
890
|
+
writes (and `design`, only when one was asked for); `build` then uses the storyboard's
|
|
891
|
+
unless `--theme`/`--design` or a config file restates one.
|
|
845
892
|
Language is never overridden at build time — it describes copy that is already written.
|
|
846
893
|
|
|
894
|
+
`--design v2` (or `"design": "v2"` in the config file) lets the build vary each beat's
|
|
895
|
+
layout: bars as rows or columns, a pipeline as a row, a stair or a column, a claim beside,
|
|
896
|
+
mirrored against or above its figure, a comparison as columns or rows, and the headline on
|
|
897
|
+
top, in a left rail or under the body. The choice is made by code, deterministically, per
|
|
898
|
+
paper — never by the planner — and it never moves a stop, so narration stays aligned.
|
|
899
|
+
`build` writes the choices to `out/look.json`. Without the flag the deck is the classic one,
|
|
900
|
+
byte for byte. See `.planning/2026-10-07-v2-layout-director.md`.
|
|
901
|
+
|
|
902
|
+
## v2 motion
|
|
903
|
+
|
|
904
|
+
`--design v2` replaces the 0.8 deck's single motion — every scene fading up the same
|
|
905
|
+
eyebrow and headline, every seam the same 0.4s dissolve, nothing moving once a slide has
|
|
906
|
+
built — with a grammar planned per deck (`src/emit/motion.ts`):
|
|
907
|
+
|
|
908
|
+
- **Entrances.** Six verbs — `rise`, `slide`, `snap`, `focus`, `wipe`, `mask` — one per
|
|
909
|
+
scene, chosen from the source id and beat id, never the same twice in a row, with the
|
|
910
|
+
stock `rise` capped at a quarter of the deck.
|
|
911
|
+
- **Seams.** `dissolve`, `push`, `lift`, `wipe`, `zoom`, picked from how two neighbouring
|
|
912
|
+
beats relate (same family → push, a role boundary → zoom, a title → lift, into the close
|
|
913
|
+
→ dissolve), never repeated back to back, and at least three kinds in a deck of ten or
|
|
914
|
+
more beats. A beat `inside` the one before keeps the camera dive.
|
|
915
|
+
- **Emphasis while the narrator talks.** The part a sentence is about pulses, glows or is
|
|
916
|
+
underlined, starting on a cue boundary of that sentence inside the quiet stretch after
|
|
917
|
+
its stop, and is back at rest before the next reveal — so every frame a gate captures
|
|
918
|
+
at a stop is unchanged.
|
|
919
|
+
|
|
920
|
+
All of it is `fromTo` tweens with no callbacks, seeded rather than random, and keeps every
|
|
921
|
+
hold, every scene window and `timing.json` exactly as `classic` writes them. In `deck.html`
|
|
922
|
+
a v2 deck also glides through the seam into the next slide (0.8 cut to its first stop,
|
|
923
|
+
already built) and, while a stop's audio plays, seeks the scene through that stop's quiet
|
|
924
|
+
stretch on the audio clock so the emphasis lands on the same word as in the video. Both
|
|
925
|
+
are off under `prefers-reduced-motion`.
|
|
926
|
+
|
|
847
927
|
## Themes
|
|
848
928
|
|
|
849
929
|
Three, each a position rather than a hue.
|
|
@@ -862,6 +942,41 @@ naming a family the deck does not declare falls back silently.
|
|
|
862
942
|
A theme is a name and a palette, and that is the whole extension point: a new one is a
|
|
863
943
|
file in `src/emit/themes/` plus a line in `THEMES`. No archetype learns it exists.
|
|
864
944
|
|
|
945
|
+
### v2 style packs
|
|
946
|
+
|
|
947
|
+
Six more, each a whole look rather than a palette: its own typeface pairing and type
|
|
948
|
+
scale, ground and accent, eyebrow treatment, figure framing and surface.
|
|
949
|
+
|
|
950
|
+
| Pack | Ground | Headline / body | Title | Lists | Bars | Leans to |
|
|
951
|
+
|---|---|---|---|---|---|---|
|
|
952
|
+
| `signal` | violet-black, Magma accent | Space Grotesk / Inter | glowing headline | ticks | pills | foot headlines |
|
|
953
|
+
| `blueprint` | navy, cyan | IBM Plex Sans / IBM Plex Sans | drawing frame with corner marks | numbers | square, on dashed tracks | rail headlines |
|
|
954
|
+
| `atlas` | espresso, amber | Source Serif 4 / Inter | centred, frontispiece rule | dots | slightly rounded | top headlines |
|
|
955
|
+
| `folio` | cream, oxblood | Source Serif 4 / Source Serif 4 | masthead rules | numbers | square, no tracks | top headlines, versus |
|
|
956
|
+
| `chalk` | cool white, ultramarine | Space Grotesk / IBM Plex Sans | highlighter under each word | cards | rounded, outlined | foot headlines, tables |
|
|
957
|
+
| `journal` | sage, forest | IBM Plex Sans / Source Serif 4 | side bar down the title | ruled rows | slightly rounded, outlined tracks | rail headlines |
|
|
958
|
+
|
|
959
|
+
The forms are the pack's `forms` (list marks, Director affinity) and its `skin` (title,
|
|
960
|
+
bars), which may set only paint: colours, shadows, radii, outlines and SVG stroke/fill
|
|
961
|
+
opacity, never a box. In a Korean, Japanese or Chinese deck a pack's serif roles are set
|
|
962
|
+
in Noto Serif KR/JP/SC, bundled beside the sans.
|
|
963
|
+
|
|
964
|
+
`--theme <pack>` forces one. `--design v2` picks one when nobody named a theme (a
|
|
965
|
+
storyboard's default `ink` counts as nobody): a weighted, deterministic hash of the
|
|
966
|
+
source id (or `--pack-seed`), leaning mildly toward packs that suit the deck's mix of
|
|
967
|
+
archetypes. Over the 176 HypePaper storyboards on disk the busiest pack carries 20.5% of
|
|
968
|
+
decks. With narration on disk, a pack that would stage a beat with a different stop count
|
|
969
|
+
than the narration was recorded at, or that would leave out a beat the storyboard's own
|
|
970
|
+
theme draws, is skipped for the next one; if none fits, the storyboard's own theme is kept.
|
|
971
|
+
So `--design v2` never breaks a narrated rebuild and never costs a slide.
|
|
972
|
+
|
|
973
|
+
Each pack's faces ship beside a Latin deck, vendored from `@fontsource-variable/*` like
|
|
974
|
+
Inter, and are measured by their own width tables (`src/emit/faces.ts`, written by
|
|
975
|
+
`node scripts/measure-faces.mjs --write`). A CJK deck keeps its Noto bundle first in every
|
|
976
|
+
stack — Noto Serif for a role the pack sets in a serif, Noto Sans otherwise — so the glyph
|
|
977
|
+
shapes change with the pack in every language.
|
|
978
|
+
The packs' interfaces are written up in `.planning/2026-10-07-v2-style-packs.md`.
|
|
979
|
+
|
|
865
980
|
## Narration
|
|
866
981
|
|
|
867
982
|
```sh
|
|
@@ -1278,6 +1393,8 @@ src/prefs.ts the three-layer preference resolver
|
|
|
1278
1393
|
src/emit/kit.ts the seam between the deck shell and the archetype emitters
|
|
1279
1394
|
src/emit/archetypes/ one emitter per archetype
|
|
1280
1395
|
src/emit/themes/ one palette per file; the registry is the extension point
|
|
1396
|
+
src/emit/type.ts type specs: the v2 packs' faces and chrome scale, read by chromeHeight and chromeCss
|
|
1397
|
+
src/emit/faces.ts measured width tables for the packs' Latin faces (generated)
|
|
1281
1398
|
src/images/ the three rungs a brief is drawn through, and the illustrate step
|
|
1282
1399
|
src/narrate/ edge-tts, one segment per stop
|
|
1283
1400
|
src/pack/ the .deck container and its bake/link/embed policy
|