reelson 0.7.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.
Files changed (105) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/LICENSE +21 -0
  3. package/NOTICE.md +15 -0
  4. package/README.md +180 -0
  5. package/bin/reelson.js +649 -0
  6. package/bin/reelson.ts +676 -0
  7. package/bin/run.js +5 -0
  8. package/demo.config.example.json +51 -0
  9. package/docs/demo.webp +0 -0
  10. package/docs/prompting.md +72 -0
  11. package/docs/style-guide.md +117 -0
  12. package/examples/demo.config.json +18 -0
  13. package/examples/todo-add-item/scenario.ts +45 -0
  14. package/examples/todo-add-item/video.json +35 -0
  15. package/music/README.md +7 -0
  16. package/package.json +68 -0
  17. package/skills/reelson-compose/SKILL.md +226 -0
  18. package/skills/reelson-compose/schemas/video.schema.json +172 -0
  19. package/skills/reelson-compose/scripts/build.js +424 -0
  20. package/skills/reelson-compose/scripts/build.ts +532 -0
  21. package/skills/reelson-compose/scripts/captions.js +24 -0
  22. package/skills/reelson-compose/scripts/captions.ts +40 -0
  23. package/skills/reelson-compose/scripts/check.js +80 -0
  24. package/skills/reelson-compose/scripts/check.ts +93 -0
  25. package/skills/reelson-compose/scripts/composition.js +163 -0
  26. package/skills/reelson-compose/scripts/composition.ts +241 -0
  27. package/skills/reelson-compose/scripts/hyperframes.js +138 -0
  28. package/skills/reelson-compose/scripts/hyperframes.ts +157 -0
  29. package/skills/reelson-compose/scripts/portrait.js +150 -0
  30. package/skills/reelson-compose/scripts/portrait.ts +218 -0
  31. package/skills/reelson-compose/scripts/project.js +238 -0
  32. package/skills/reelson-compose/scripts/project.ts +324 -0
  33. package/skills/reelson-compose/scripts/studio.js +330 -0
  34. package/skills/reelson-compose/scripts/studio.ts +394 -0
  35. package/skills/reelson-compose/scripts/timeline.js +271 -0
  36. package/skills/reelson-compose/scripts/timeline.ts +514 -0
  37. package/skills/reelson-compose/scripts/tts.js +303 -0
  38. package/skills/reelson-compose/scripts/tts.ts +371 -0
  39. package/skills/reelson-compose/scripts/verify.js +190 -0
  40. package/skills/reelson-compose/scripts/verify.ts +209 -0
  41. package/skills/reelson-compose/scripts/voice.js +178 -0
  42. package/skills/reelson-compose/scripts/voice.ts +224 -0
  43. package/skills/reelson-compose/scripts/zooms.js +259 -0
  44. package/skills/reelson-compose/scripts/zooms.ts +333 -0
  45. package/skills/reelson-compose/sections/README.md +5 -0
  46. package/skills/reelson-compose/sections/intro/minimal/section.css +27 -0
  47. package/skills/reelson-compose/sections/intro/minimal/section.html +12 -0
  48. package/skills/reelson-compose/sections/intro/minimal/section.js +16 -0
  49. package/skills/reelson-compose/sections/intro/minimal/section.json +9 -0
  50. package/skills/reelson-compose/sections/intro/poster/section.css +27 -0
  51. package/skills/reelson-compose/sections/intro/poster/section.html +14 -0
  52. package/skills/reelson-compose/sections/intro/poster/section.js +28 -0
  53. package/skills/reelson-compose/sections/intro/poster/section.json +9 -0
  54. package/skills/reelson-compose/sections/intro/split/section.css +30 -0
  55. package/skills/reelson-compose/sections/intro/split/section.html +12 -0
  56. package/skills/reelson-compose/sections/intro/split/section.js +19 -0
  57. package/skills/reelson-compose/sections/intro/split/section.json +9 -0
  58. package/skills/reelson-compose/sections/outro/compact/section.css +23 -0
  59. package/skills/reelson-compose/sections/outro/compact/section.html +10 -0
  60. package/skills/reelson-compose/sections/outro/compact/section.js +11 -0
  61. package/skills/reelson-compose/sections/outro/compact/section.json +8 -0
  62. package/skills/reelson-compose/sections/outro/endcard/section.css +25 -0
  63. package/skills/reelson-compose/sections/outro/endcard/section.html +13 -0
  64. package/skills/reelson-compose/sections/outro/endcard/section.js +13 -0
  65. package/skills/reelson-compose/sections/outro/endcard/section.json +8 -0
  66. package/skills/reelson-compose/sections/outro/wordmark/section.css +11 -0
  67. package/skills/reelson-compose/sections/outro/wordmark/section.html +5 -0
  68. package/skills/reelson-compose/sections/outro/wordmark/section.js +12 -0
  69. package/skills/reelson-compose/sections/outro/wordmark/section.json +8 -0
  70. package/skills/reelson-compose/sections/recap/compact/section.css +26 -0
  71. package/skills/reelson-compose/sections/recap/compact/section.html +8 -0
  72. package/skills/reelson-compose/sections/recap/compact/section.js +23 -0
  73. package/skills/reelson-compose/sections/recap/compact/section.json +11 -0
  74. package/skills/reelson-compose/sections/recap/steps/section.css +36 -0
  75. package/skills/reelson-compose/sections/recap/steps/section.html +8 -0
  76. package/skills/reelson-compose/sections/recap/steps/section.js +27 -0
  77. package/skills/reelson-compose/sections/recap/steps/section.json +11 -0
  78. package/skills/reelson-compose/studio/index.html +81 -0
  79. package/skills/reelson-compose/studio/studio.css +142 -0
  80. package/skills/reelson-compose/studio/studio.js +1031 -0
  81. package/skills/reelson-compose/templates/README.md +193 -0
  82. package/skills/reelson-compose/templates/classic/assets/vendor/Inter-OFL.txt +93 -0
  83. package/skills/reelson-compose/templates/classic/assets/vendor/gsap.min.js +11 -0
  84. package/skills/reelson-compose/templates/classic/assets/vendor/inter-latin-ext-wght-normal.woff2 +0 -0
  85. package/skills/reelson-compose/templates/classic/assets/vendor/inter-latin-wght-normal.woff2 +0 -0
  86. package/skills/reelson-compose/templates/classic/stage.html +447 -0
  87. package/skills/reelson-compose/templates/classic/template.json +5 -0
  88. package/skills/reelson-record/SKILL.md +220 -0
  89. package/skills/reelson-record/schemas/demo.config.schema.json +269 -0
  90. package/skills/reelson-record/scripts/capture.js +142 -0
  91. package/skills/reelson-record/scripts/capture.ts +190 -0
  92. package/skills/reelson-record/scripts/config.js +148 -0
  93. package/skills/reelson-record/scripts/config.ts +264 -0
  94. package/skills/reelson-record/scripts/cursor-overlay.js +111 -0
  95. package/skills/reelson-record/scripts/cursor-overlay.ts +122 -0
  96. package/skills/reelson-record/scripts/doctor.js +128 -0
  97. package/skills/reelson-record/scripts/doctor.ts +147 -0
  98. package/skills/reelson-record/scripts/languages.js +29 -0
  99. package/skills/reelson-record/scripts/languages.ts +41 -0
  100. package/skills/reelson-record/scripts/record.js +365 -0
  101. package/skills/reelson-record/scripts/record.ts +451 -0
  102. package/skills/reelson-record/scripts/scenario.js +356 -0
  103. package/skills/reelson-record/scripts/scenario.ts +570 -0
  104. package/skills/reelson-record/scripts/validate.js +143 -0
  105. package/skills/reelson-record/scripts/validate.ts +179 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,99 @@
1
+ # Changelog
2
+
3
+ All notable changes to reelson. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
4
+ versions follow [Semantic Versioning](https://semver.org/) (before 1.0, a minor version may change
5
+ `video.json` or `demo.config.json`; the notes say how to update).
6
+
7
+ ## 0.7.0 — 2026-09-23
8
+
9
+ The first release on npm.
10
+
11
+ ### Changed
12
+ - **Renamed reelkit → reelson**: the `reelson` command, the `reelson-record` / `reelson-compose`
13
+ skills, the Piper cache in `~/.cache/reelson`. Re-run `reelson install` (or `install.sh`) for each
14
+ project: it drops the old `reelkit` command and `reelkit-*` skill links. Then point scenario
15
+ imports and `$schema` paths at `.claude/skills/reelson-*`.
16
+
17
+ ### Added
18
+ - **npm package** (MIT): `npm install -g reelson`. It ships JavaScript compiled beside the
19
+ TypeScript sources; a checkout still runs the sources directly.
20
+ - **`reelson install [<dir> | --global] [--no-browser]`**: links the skills into a project (or
21
+ `~/.claude/skills`), creates `demo.config.json` and downloads Playwright's Chromium.
22
+ `install.sh` now `npm link`s a checkout and calls it.
23
+ - **Voice-over providers**: `voice.provider` picks `openai` (or an OpenAI-compatible server via
24
+ `baseURL`), `elevenlabs`, `piper` (a local neural voice, downloaded on first use) or `command` (any
25
+ local program); speed, options and per-video provider/model/voice overrides. Lines are trimmed of
26
+ the silence around them. `reelson voices` lists the voices (`--library`: the ElevenLabs Voice Library);
27
+ `reelson doctor` says whether the provider can speak here.
28
+ - A spoken callout stays up until its line is said, and the next step waits for it (`build` and `check`
29
+ warn when a line cannot fit). API keys are read from a `.env` beside `demo.config.json` or in the
30
+ reelson install; the environment wins.
31
+
32
+ ### Fixed
33
+ - `render --gif` works again: the GIF (720 px, 12 fps) is now cut from the rendered MP4 with ffmpeg
34
+ instead of HyperFrames' GIF encoder, which failed with ffmpeg 7.0 and rendered every frame a second
35
+ time. It is skipped while the MP4 is unchanged.
36
+ - `moveTo` scrolls an out-of-sight target into view smoothly instead of jumping.
37
+ - The voice track is resampled to 48 kHz and padded so it never falls short of its slot.
38
+
39
+ ## 0.6.0 — 2026-09-22
40
+
41
+ ### Added
42
+ - **Portrait** (1080×1920): a phone take (`record --mobile`, a Playwright device) in a phone frame,
43
+ or a camera that frames each element of the desktop take; `video.json` `"portrait": auto|mobile|desktop`.
44
+ Every kit section has its own portrait layout.
45
+ - **Square** (1080×1080): a square take (`record --square`) filling the frame, with square layouts for
46
+ every section.
47
+ - `record --all-takes`, `verify` covers every take, `render --all-formats` and `--only <format>`.
48
+ - **Voice-over**: `"voice": true` speaks each callout (its `say`, else its text) with OpenAI
49
+ text-to-speech, cached in `<demo>/voice/`; the build mixes the track and ducks the music.
50
+ - Pop-ups and new tabs: `demo.popup()` / `switchTo()` move the demo and the camera there and back.
51
+
52
+ ### Changed
53
+ - Callouts start with their step (not after its marker), get a minimum reading time, and move to the
54
+ top over action at the bottom of the screen.
55
+ - `reelson check` lints each composition on its own.
56
+
57
+ ## 0.5.0 — 2026-09-22
58
+
59
+ ### Added
60
+ - **Screencast capture**: Chrome's screencast films every painted frame on the cursor's clock →
61
+ a smooth 30 fps recording (`record.capture "playwright"` keeps the old 25 fps video).
62
+ - Zooms can follow the cursor (`"follow"`); the cursor fades when idle (`"cursor": { "idle": s }`).
63
+ - Trims follow the footage (`"auto"`, marker and click anchors); `check` warns about fixed times.
64
+ - `render --draft` (15 fps, ~2× faster); renders are skipped when nothing changed (`--force`).
65
+ - `.srt` / `.vtt` captions; `--square` / `--portrait` social versions.
66
+ - `reelson doctor`: the tools, plus a measured cursor-to-footage sync on this machine.
67
+ - `reelson verify`: re-records every demo into a scratch folder and checks `video.json` still fits.
68
+ - Built-in recap strings and plural forms for 18 languages; more dev toolbars hidden by default.
69
+
70
+ ## 0.4.0 — 2026-09-22
71
+
72
+ ### Added
73
+ - **Cursor as a layer**: logged by the page, drawn by the video, so it stays smooth and the same
74
+ size under zooms, and can be restyled without re-recording. Clicks land where the glide ends.
75
+ - **Studio** (`reelson studio`): a preview with a layer timeline; edit callouts, trims, zooms, sections
76
+ and titles (saved to `video.json`, with undo).
77
+
78
+ ### Fixed
79
+ - Dev-chrome hiding works again (the injected script had a syntax error since 0.2).
80
+ - Scenarios use the project's Playwright, so they can import its helpers.
81
+
82
+ ## 0.3.0 — 2026-09-22
83
+
84
+ ### Added
85
+ - Templates are a stage plus mix-and-match sections per slot: intro (`poster`, `minimal`, `split`),
86
+ recap (`steps`, `compact`, `none`), outro (`wordmark`, `compact`, `endcard`), chosen in
87
+ `demo.config.json`, `video.json` or with `--intro` / `--recap` / `--outro`.
88
+ - `brand.logo` replaces the text wordmark; `reelson templates` lists what is available.
89
+
90
+ ## 0.2.0 — 2026-09-21
91
+
92
+ ### Added
93
+ - `video.json` as the source of truth for a video (zooms anchored by click number, auto-timed).
94
+ - The CLI: `init`, `new`, `record`, `build`, `check`, `snapshot`, `preview`, `render`.
95
+ - Validation against JSON Schemas with "did you mean" hints, unit and golden tests, CI.
96
+
97
+ ## 0.1.0 — 2026-09-21
98
+
99
+ - The first kit: a recording skill and a composing skill, the classic template, branding from config.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ion Caliman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/NOTICE.md ADDED
@@ -0,0 +1,15 @@
1
+ # Third-party notices
2
+
3
+ reelson ships or downloads the following. Check each licence before using reelson output
4
+ commercially or redistributing it.
5
+
6
+ | Component | Where | Licence |
7
+ |---|---|---|
8
+ | **GSAP 3.14.2** (GreenSock) | vendored: `skills/reelson-compose/templates/classic/assets/vendor/gsap.min.js` | GreenSock Standard "No Charge" License — https://gsap.com/standard-license (not an OSI licence) |
9
+ | **Inter** variable font 4.x (Rasmus Andersson), via `@fontsource-variable/inter` 5.3.0 | vendored: `…/classic/assets/vendor/inter-*.woff2` | SIL Open Font License 1.1 — `…/classic/assets/vendor/Inter-OFL.txt` |
10
+ | **Playwright** (Microsoft) | npm dependency | Apache-2.0 |
11
+ | **HyperFrames** (HeyGen) | fetched by `npx` at render/check time | see https://hyperframes.heygen.com |
12
+ | **FFmpeg** | system dependency, not bundled | LGPL/GPL depending on the build |
13
+ | **TypeScript**, **@types/node** | dev dependencies | Apache-2.0 / MIT |
14
+
15
+ Music is not included: stock-music licences are registered per project (see `music/README.md`).
package/README.md ADDED
@@ -0,0 +1,180 @@
1
+ # reelson
2
+
3
+ Turn a prompt into a finished, branded demo video of a web app. Two
4
+ [Claude Code](https://claude.com/claude-code) skills plus a `reelson` CLI:
5
+
6
+ | Skill | Does | Output |
7
+ |------------------------------------------|-----------------------------------------------------------------------------|------------------------------------------|
8
+ | [`reelson-record`](skills/reelson-record/) | Playwright walkthrough with a visible human-paced cursor, dev chrome hidden, step markers and logged clicks | `<slug>/recording.mp4` + `markers.json` |
9
+ | [`reelson-compose`](skills/reelson-compose/) | [HyperFrames](https://hyperframes.heygen.com) composition from a template + mix-and-match intro/recap/outro sections: poster intro, framed recording, callouts, cursor-timed zooms, recap, brand outro, music | `<slug>/video/renders/<slug>.mp4` |
10
+
11
+ The same prompt re-creates the video after a UI change: a scenario re-records in ~20 s,
12
+ headless, with identical pacing, and callouts/zooms follow their markers and clicks.
13
+
14
+ ![The TodoMVC example: poster intro, the recorded walkthrough with callouts and zooms, recap and outro](https://cdn.jsdelivr.net/npm/reelson/docs/demo.webp)
15
+
16
+ <sub>The [example](examples/todo-add-item/scenario.ts), rendered by CI on every push
17
+ (`docs/demo.webp` is a 960 px cut of it).</sub>
18
+
19
+ ```
20
+ scenario.ts ──reelson record──▶ recording.mp4 + markers.json
21
+
22
+ video.json (title, trim, callouts, zooms) ┴──reelson build──▶ video/ ──reelson render──▶ .mp4 / .gif
23
+ demo.config.json (brand, logo, language, music) + template + sections ┘
24
+ ```
25
+
26
+ ## Requirements
27
+
28
+ - Node 22.18+ and `ffmpeg` (`brew install ffmpeg`)
29
+ - The app you record, running locally
30
+ - HyperFrames is fetched by `npx` on first use (version pinned in
31
+ [hyperframes.ts](skills/reelson-compose/scripts/hyperframes.ts))
32
+
33
+ ## Install
34
+
35
+ ```bash
36
+ npm install -g reelson
37
+ reelson install ~/code/my-app # or: reelson install --global (~/.claude/skills, every project)
38
+ ```
39
+
40
+ `reelson install` downloads Playwright's Chromium, links both skills into
41
+ `my-app/.claude/skills/`, creates `my-app/demo.config.json` and prints the `.gitignore` lines.
42
+ The links point at the installed package, so `npm update -g reelson` updates every project.
43
+
44
+ To work on reelson itself, install from a checkout instead: the `reelson` command then runs the
45
+ TypeScript sources directly and `git pull` updates every project.
46
+
47
+ ```bash
48
+ git clone git@github.com:reelson/reelson.git ~/reelson
49
+ ~/reelson/install.sh ~/code/my-app # npm link + reelson install
50
+ ```
51
+
52
+ reelson was called reelkit before 0.7. Re-run `reelson install` (or `install.sh`) for each project: it drops the old
53
+ `reelkit` command and `reelkit-*` skill links. Then point scenario imports and `$schema` paths
54
+ at `.claude/skills/reelson-*`.
55
+
56
+ ## Configure per project — `demo.config.json`
57
+
58
+ Everything project-specific lives in one file at the project root. It is validated against
59
+ [a JSON Schema](skills/reelson-record/schemas/demo.config.schema.json) (editors autocomplete it; a
60
+ typo is an error with a "did you mean" hint).
61
+
62
+ ```jsonc
63
+ {
64
+ "videosDir": "docs/videos", // where <slug>/ folders live
65
+ "language": "en", "locale": "en-US", // UI language: plurals, personas, <html lang>
66
+ "brand": { "name": "ACME", "tagline": "PLATFORM", "eyebrow": "Acme",
67
+ "color": "#dc2626", "colorSoft": "#f87171",
68
+ "logo": "docs/brand/logo.svg" }, // optional: replaces the text wordmark
69
+ "template": "classic",
70
+ "sections": { "intro": "poster", "recap": "steps", "outro": "wordmark" }, // the defaults
71
+ "strings": { // optional: built in for en, ro, de, fr, es, it,
72
+ "recapTitle": "In short", // pt, nl, pl, ru, uk, cs, sv, da, nb, fi, hu, tr
73
+ "stepsLabel": { "one": "step", "other": "steps" }, // Intl.PluralRules categories
74
+ "secondsLabel": { "one": "second", "other": "seconds" } // e.g. ro: one/few/other
75
+ },
76
+ "music": { "file": "docs/videos/_music/track.mp3", "lufs": -28, "lufsUnderNarration": -34 },
77
+ "record": {
78
+ "viewport": { "width": 1440, "height": 900 },
79
+ "hideSelectors": [".environment-indicator"], // local-only UI to hide on camera
80
+ "extraHTTPHeaders": { "X-Demo-Recording": "1" },
81
+ "personaDomain": "example.com",
82
+ "cursor": "layer", // or "recorded": film it into the footage
83
+ "capture": "screencast" // every painted frame → smooth 30 fps (or "playwright")
84
+ }
85
+ }
86
+ ```
87
+
88
+ ## Use
89
+
90
+ Ask Claude in the project, e.g.:
91
+
92
+ > Make a demo video of searching a customer. Admin area on https://app.test as the admin.
93
+ > Steps: open Customers, type a name in the table search, hover the match. Title "Find a
94
+ > customer". Zoom on the search box while typing. Slug customers-search.
95
+
96
+ More prompts in [docs/prompting.md](docs/prompting.md); the rules every video follows in
97
+ [docs/style-guide.md](docs/style-guide.md). By hand:
98
+
99
+ ```bash
100
+ reelson doctor # tools + cursor/footage sync on this machine
101
+ reelson new customers-search --url https://app.test # scenario stub
102
+ reelson record customers-search [--headed] # --mobile / --square: the takes for --portrait / --square; --all-takes: all three
103
+ reelson build customers-search --title "Find a customer" # creates video.json on first run
104
+ # edit video.json: callout wording, { "clicks": [2, 3], "scale": 1.8 } zooms, trim ("auto" or a marker)
105
+ reelson voice customers-search # "voice": true in video.json: speak the callouts (voice.provider: openai, elevenlabs, piper, command)
106
+ reelson check customers-search # schemas, zoom timing, hyperframes lint
107
+ reelson verify --all # after an app change: every demo still records and fits
108
+ reelson studio customers-search # preview + edit on a layer timeline (saves video.json)
109
+ reelson templates # templates and intro/recap/outro sections
110
+ reelson render customers-search [--gif] [--square] [--portrait] [--all-formats] [--draft] # + .srt/.vtt captions
111
+ reelson render --all # every demo; skips the unchanged ones
112
+ ```
113
+
114
+ Per video, commit `scenario.ts`, `markers.json` and `video.json`; everything else is generated.
115
+
116
+ ## Templates and sections
117
+
118
+ A video is a **template** (the stage: background, framed recording, callouts) plus one
119
+ **section** per slot, chosen separately in demo.config.json or per video in video.json:
120
+
121
+ | Slot | Sections (first = default) |
122
+ |---------|----------------------------------------------|
123
+ | `intro` | `poster`, `minimal`, `split` |
124
+ | `recap` | `steps`, `compact`, `none` |
125
+ | `outro` | `wordmark`, `compact`, `endcard` |
126
+
127
+ ```jsonc
128
+ // video.json — this video only
129
+ "sections": { "intro": "minimal", "recap": "none", "outro": "endcard" }
130
+ ```
131
+
132
+ Every intro keeps frame 0 as the poster and every outro ends on the brand, so any mix keeps
133
+ the house style. `brand.logo` (an SVG, or a PNG ≥ 340 px tall) replaces the text wordmark in all
134
+ of them. `classic` is the only template today. The contract for new templates and sections is in
135
+ [templates/README.md](skills/reelson-compose/templates/README.md); a project can keep its own under
136
+ `<videosDir>/_templates/<name>/` and `<videosDir>/_sections/<slot>/<name>/`. Templates ship
137
+ their scripts and fonts (no CDN).
138
+
139
+ ## Develop
140
+
141
+ ```bash
142
+ npm run setup # deps + Chromium
143
+ npm run typecheck # tsc --noEmit
144
+ npm test # unit + golden tests (node:test)
145
+ npm run test:update-golden # after an intended template/composition change — review the diff
146
+ npm run example:record && npm run example:build && npm run example:check && npm run example:render
147
+ ```
148
+
149
+ CI ([.github/workflows/ci.yml](.github/workflows/ci.yml)) runs the type check and tests, then
150
+ records the TodoMVC example, builds, checks and renders it, and uploads the MP4 and frames.
151
+
152
+ ### Publish to npm
153
+
154
+ Node will not run TypeScript from under `node_modules`, so the package ships `.js` compiled beside
155
+ each `.ts` (`npm run build`; `npm pack` / `npm publish` build first and clean up after).
156
+ `bin/run.js` picks the compiled CLI when installed from npm and the sources in a checkout.
157
+
158
+ 1. Bump `version` in package.json, commit, tag `vX.Y.Z` and push the tag.
159
+ 2. [.github/workflows/publish.yml](.github/workflows/publish.yml) runs the checks and publishes
160
+ with npm trusted publishing (OIDC, with provenance; no token). Set it up once on npmjs.com →
161
+ the package → Settings → Trusted publishing: GitHub Actions, `reelson/reelson`, `publish.yml`.
162
+
163
+ The very first release has to be published by hand (trusted publishing needs the package to
164
+ exist): `npm login && npm publish`. Check the contents first with `npm pack --dry-run`.
165
+
166
+ ## Layout
167
+
168
+ ```
169
+ bin/reelson.ts the CLI (run.js: the npm entry point)
170
+ skills/
171
+ reelson-record/ SKILL.md, scripts/ (record, scenario, cursor-overlay, config, validate), schemas/
172
+ reelson-compose/ SKILL.md, scripts/ (build, check, timeline, zooms, composition, project, hyperframes),
173
+ schemas/, templates/<name>/ (stages), sections/<slot>/<name>/
174
+ docs/ style-guide.md, prompting.md, demo.webp (the README clip)
175
+ examples/ demo.config.json + todo-add-item/ (scenario, markers, video.json)
176
+ test/ unit + golden tests, fixtures
177
+ music/ local-only tracks (git-ignored; licences are per project)
178
+ ```
179
+
180
+ MIT licence ([LICENSE](LICENSE)). Third-party code and fonts: [NOTICE.md](NOTICE.md).