reelkit-cli 0.12.3 → 0.12.4

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/CHANGELOG.md CHANGED
@@ -3,6 +3,10 @@
3
3
  What changed in each published version of `reelkit-cli`, newest first. A push to `main` publishes the version in
4
4
  `package.json` when it is not on npm yet, and it must have an entry here.
5
5
 
6
+ ## 0.12.4 - 2026-10-09
7
+
8
+ - A template's timeline shows the music and its beats to the end of the film when the track repeats, not only for the track's own length.
9
+
6
10
  ## 0.12.3 - 2026-10-09
7
11
 
8
12
  - A template's components are tied to scenes in more of the ways compositions are written: a project's own helper that is handed a scene's id, a lookup by id, a list that pairs ids with components, a branch on a scene's id, and components the file declares for itself.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reelkit-cli",
3
- "version": "0.12.3",
3
+ "version": "0.12.4",
4
4
  "description": "CLI and Claude skill for making short-form video with a shared asset library.",
5
5
  "license": "MIT",
6
6
  "author": "Daniel Livshin",
package/skill/SKILL.md CHANGED
@@ -15,7 +15,7 @@ For image or video cutouts, editable Blender product shots, custom 3D materials,
15
15
 
16
16
  To implement a chosen style, read its row in `reference/style-recipes.md` for action, timing, sound and proof. `reference/style-components.md` maps the shared components and built-in kit to shot roles; inspect the selected source before using its props.
17
17
 
18
- This skill targets `reelkit-cli` 0.12.3 and its HyperFrames kit. Check the installed version with `reelkit --version`; in a source checkout, invoke its `bin/reelkit.mjs` with Node. Use the matching CLI before authoring with `reelkit/frame`.
18
+ This skill targets `reelkit-cli` 0.12.4 and its HyperFrames kit. Check the installed version with `reelkit --version`; in a source checkout, invoke its `bin/reelkit.mjs` with Node. Use the matching CLI before authoring with `reelkit/frame`.
19
19
 
20
20
  ## What decides whether the film is accepted
21
21
 
@@ -61,7 +61,7 @@ export function filmOf(project: Project): TemplateFilm | undefined {
61
61
  ...(used.some((c) => c.scenes.includes(m.id)) ? { components: used.filter((c) => c.scenes.includes(m.id)).map((c) => cut(c.name, 80)).slice(0, 60) } : {}),
62
62
  };
63
63
  }),
64
- ...(music ? { music: { title: cut(music.title, 200), seconds: music.durationSec, ...(music.bpm ? { bpm: music.bpm } : {}), beats: music.beats.filter((b) => b >= 0 && b <= seconds).slice(0, 4000), ...(music.id ? { id: cut(music.id, 128) } : {}) } } : {}),
64
+ ...(music ? { music: musicOf(music, manifest, seconds) } : {}),
65
65
  ...(used.length ? { components: used.slice(0, 300).map((c) => { const text = c.from === "kit" ? undefined : about(c.name); return { name: cut(c.name, 80), from: c.from, uses: c.uses, ...(text ? { about: cut(text, 400) } : {}) }; }) } : {}),
66
66
  voice: plan.voice !== "none",
67
67
  ...(manifest.captions ? { captions: manifest.captions } : {}),
@@ -69,6 +69,19 @@ export function filmOf(project: Project): TemplateFilm | undefined {
69
69
  };
70
70
  }
71
71
 
72
+ // The music as it plays in the film. A track shorter than the film is repeated by the composition, and the manifest holds every beat
73
+ // that falls inside the film (the repeats too), so those are the beats shown; the track then runs to the film's end. Without them the
74
+ // track's own beats and length are used.
75
+ function musicOf(music: MusicRecord, manifest: AssetManifest, seconds: number): NonNullable<TemplateFilm["music"]> {
76
+ const inFilm = (manifest.music?.beatFrames ?? []).map((f) => Math.round((f / manifest.fps) * 1000) / 1000).filter((b) => b >= 0 && b <= seconds);
77
+ const beats = (inFilm.length ? inFilm : music.beats.filter((b) => b >= 0 && b <= seconds)).slice(0, 4000);
78
+ const repeats = inFilm.length > 0 && inFilm[inFilm.length - 1]! > music.durationSec;
79
+ return {
80
+ title: music.title.slice(0, 200), seconds: repeats ? seconds : Math.min(music.durationSec, seconds), ...(music.bpm ? { bpm: music.bpm } : {}), beats,
81
+ ...(music.id ? { id: music.id.slice(0, 128) } : {}),
82
+ };
83
+ }
84
+
72
85
  // The sound effects by name, from what the last render recorded (out/sounds.json): every sound that is not the music or a scene's
73
86
  // voice, with the title it has in the library when it was pulled from there, or its file name.
74
87
  function cuesOf(project: Project, manifest: AssetManifest, musicKey: string | undefined): Pick<TemplateFilm, "cues"> {