13 Commits

Author SHA1 Message Date
Conal Mullan 9dc31ac983 DEPS: bump Remotion 4.0.425 → 4.0.518 across templates, examples, showcase, tests (#67)
Re-landing #66 against main (it merged into its stacked base after that
branch had already been merged). Produced by scripts/bump_remotion.py
--smoke: lockfiles refreshed, frame-0 smoke render OK for all 8 projects
with an entry point, render-baseline A/B identical on all six frames.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 09:49:19 +01:00
Conal Mullan 9dc833397a FEAT: scripts/check_versions.py — toolkit-wide Remotion/Python/toolkit staleness check, wired into /versions (#63)
Deterministic data source for /versions (#23 part 1): every Remotion pin
under templates/, examples/, showcase/, tests/ vs latest npm (patches
behind, pin age), flags caret ranges and disagreeing pins; uv.lock vs
pyproject plus outdated direct Python deps; registry vs latest release.
--json / --offline / --strict.

Also pins the stragglers it found to the template version 4.0.425:
sprint-review-cho-oyu (4.0.381), digital-samba-skill-demo (4.0.382),
showcase/transitions and showcase/banner (^4.0.0). Lockfiles refreshed.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 09:29:58 +01:00
Conal Mullan 290d7d345b Adopt uv for Python dependency management (#33 rebased, thanks @AsharibAli) (#59)
* Adopt uv for Python dependency management

Replace manual pip/venv setup with `uv sync` (pyproject.toml + uv.lock),
and switch all tool invocations across docs, skills, commands, and
examples to `uv run`. Optional extras: --extra whisper, --extra modal.
tools/requirements.txt is kept as a pip fallback.

* FIX: bring uv migration current with main — post-June deps and docs

Adds websocket-client (60db websocket transport) to core deps and a
'youtube' extra for the google-* packages (tools/youtube_upload.py),
regenerates uv.lock, bumps pyproject version to 0.18.0, and converts the
51 'python3 tools/…' invocations added since the PR was opened (60db,
YouTube, Kiro docs, publish command) to 'uv run'. Verified with
uv sync --frozen --extra youtube; voiceover, sixtydb_tts, youtube_upload
and migrate_to_kiro all run through the project environment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Asharib Ali <asharibarain4@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-26 22:55:43 +01:00
Conal Mullan fbd3f6bd56 CHORE: untrack the duplicate project copies under projects/
projects/sprint-review-cho-oyu and projects/digital-samba-skill-demo have been
tracked since the initial release (fde30d3, 2025-12-09). .gitignore has listed
projects/ since that same commit, but ignore rules never apply to already-tracked
files, so the rule has been silently inert on these 67 files for the repo's whole
life.

Both were superseded the next day by 0d96c3b, which created examples/ and added
curated copies of both — with README.md and ASSETS-NEEDED.md written for public
consumption. The projects/ copies are the raw working originals; they carry
.DS_Store, .claude/, node_modules/, out/ and .venv alongside them. Only the
curated examples/ copies were ever meant to ship.

Removed from the index only (git rm --cached) — the local working copies stay on
disk, and projects/ now behaves as documented: local video work, not toolkit
content.

Eight media files existed only under projects/. Seven are audio that
examples/*/ASSETS-NEEDED.md already documents as regenerable via
/generate-voiceover, tools/music.py and tools/sfx.py. The eighth, build-app.cast,
was referenced by three examples/ docs but shipped nowhere, so ASSETS-NEEDED.md
now documents recording and converting it — matching how every other asset in
these examples is handled.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019s6SvNiz9a8XpD8r2cQTiq
2026-08-26 21:31:06 +01:00
Conal Mullan 6db40e9299 Add concept-explainer-short template: 9:16 TikTok/Reels explainer shorts (Python/moviepy) (#31)
* Add concept-explainer-short template: 9:16 TikTok/Reels explainer shorts (Python/moviepy)

First non-Remotion template. The whole video derives from scenes.json
(per-scene narration text + visual asset); a three-script pipeline turns
it into a finished vertical short:

- gen_vo.py — per-scene TTS via tools/voiceover.py (clone or built-in
  speaker, batch mode, --max-wpm pacing clamp), writes the
  vo_durations.json timeline anchor; warns past the 3-minute
  Shorts/Reels ceiling
- gen_captions.py — burned karaoke caption timing: whisper word
  timestamps force-aligned to the ground-truth script text via difflib
  (never burns whisper's own transcription, which mishears TTS)
- build.py — audio-anchored moviepy composite: Ken Burns on stills,
  boomerang-looped clips (asset extension decides), caption pills with
  width cap and platform-safe positioning, ducked looped music; renders
  at every stage (gradient placeholder cards before assets exist,
  word-count timing estimates before VO, silent before audio)

Pattern proven on a 3:41 hallucinations explainer; tested end-to-end
(out-of-box placeholder render + full Modal clone pipeline with three
takes auto-clamped 181-188→165 wpm). Registered in the toolkit registry,
CLAUDE.md, and /video (with Python-flow notes); openai-whisper documented
as an optional dependency.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add sky-blue-short showcase example + fix Modal qwen3-tts batch custom_voice

examples/sky-blue-short: complete worked example of the
concept-explainer-short template — a 52s vertical "Why is the sky blue?"
short with Qwen3 VO (built-in Ryan, warm tone), two Ideogram diagram/CTA
cards, two LTX sky clips, ACE-Step music bed, and burned aligned captions
(~$0.80 total generation cost). All source assets committed; re-renders
in place with python3 build.py.

Building it surfaced two real bugs, fixed here:
- Modal qwen3-tts handler: batch custom_voice hit the same qwen-tts
  tensor-aliasing crash the clone path already works around — now
  iterates per text with the shared speaker (redeployed and verified)
- gen_vo.py: failed batch scenes crashed with KeyError instead of
  reporting which scenes failed and why

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add hallucinations-short and sky-blue-short demo videos to README showcase

Both produced with the concept-explainer-short pipeline: sky-blue-short
uses the stock Qwen3-TTS Ryan voice; hallucinations-short uses a Qwen3
voice clone from a Pixabay voice-over sample.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 07:58:39 +01:00
Conal Mullan c16c7fed29 FIX: pin Remotion to exact versions in lab examples for reproducibility
The two examples used "^4.0.0" instead of pinned versions, so running
"rm -rf node_modules && npm install" today would resolve to whatever's
current on npm (4.0.464+) rather than the version the example was
authored and rendered against.

Pins each example to its own lockfile-resolved version:
- digital-samba-skill-demo: 4.0.382
- sprint-review-cho-oyu:    4.0.381

Manifest now matches lockfile; npm install dry-run confirms no installed
versions change. Matches the exact-pin convention used across the
toolkit's templates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 22:16:03 +01:00
Conal Mullan 3f7d2c1e0b EXAMPLE: add ds-crt-stinger — CRT LoRA + grunged logo stinger
Curated reference showing the LTX-2 crt-terminal LoRA producing amber
phosphor footage, plus a PIL post-processing chain that tints the white
SVG wordmark, adds a phosphor halo, scanlines, chromatic aberration and
grain so the brand mark reads as part of the same CRT world. moviepy
composites the crossfade + hold. Self-bootstraps from the committed SVG
and the one LTX-2 output we couldn't cheaply reproduce locally.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 22:25:00 +01:00
Conal Mullan 3057ab88cc FIX: cross-platform font loading in moviepy examples
Both examples/quick-spot/build.py and examples/data-viz-chart/build.py
hardcoded `/System/Library/Fonts/Supplemental/Arial Bold.ttf` and would
crash with FileNotFoundError on Linux or Windows when PIL tried to open
the font — despite the READMEs promising the examples run with "zero
external assets."

Replaced with a `platform.system()`-keyed fallback chain:

  - Darwin  → Arial Bold / Arial (Supplemental, then /Library/Fonts)
  - Linux   → DejaVu Sans Bold / DejaVu Sans (multiple path locations)
  - Windows → arialbd.ttf / arial.ttf

If none of the candidate paths resolve (exotic distro, minimal install,
etc.), falls back to PIL's bitmap `load_default()` so the example still
runs — ugly rendering but no crash.

Verified by deleting both .text_cache directories and re-rendering both
examples on macOS. Output is visually identical to previous runs because
the macOS paths are still the first candidates in the fallback chain.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 13:11:14 +01:00
Conal Mullan 6f94523345 DEPS: declare moviepy/Pillow/matplotlib in tools/requirements.txt
The two new moviepy examples (quick-spot, data-viz-chart) imported
moviepy, Pillow, and matplotlib but had no declaration anywhere in
the toolkit — anyone cloning the repo and running `python3 build.py`
would hit a bare ModuleNotFoundError with no guidance.

This also fixes a pre-existing latent gap: tools/flux2.py and
tools/image_edit.py both `from PIL import Image` inside a try/except
guard but Pillow was never declared in tools/requirements.txt either.
The "friendly error" message was the only signal users got that they
needed to install Pillow themselves. Adding Pillow to the central
file as a free rider.

Changes
-------
- tools/requirements.txt: adds Pillow>=10.0, moviepy>=2.0, matplotlib>=3.7
  with comments explaining which tools/examples use each
- examples/quick-spot/build.py, examples/data-viz-chart/build.py: wrap
  the third-party imports in a try/except ImportError matching the
  existing flux2.py/image_edit.py pattern, with a precise error
  message pointing at `python3 -m pip install -r tools/requirements.txt`
- examples/*/README.md: Quick Start now lists the toolkit-level pip
  install as step one, then `python3 build.py`
- README.md: updates the optional Python install callout to use
  `python3 -m pip install` (avoids the pip/python3 env mismatch
  footgun) and mentions moviepy examples alongside AI voiceover/
  image gen/music in the "what this installs" note
- .claude/skills/moviepy/SKILL.md: adds a short Dependencies note so
  Claude Code knows where the deps live and what to run on ImportError

Net effect: one install command covers every Python feature in the
toolkit. Both AI agents (via stderr-reactive friendly errors) and
humans (via the README Quick Start) can recover from a missing-dep
state without guesswork.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 08:51:57 +01:00
Conal Mullan 2a638fe3d8 EXAMPLE: add hello-world — the quick-start the README already promised
The root README has been pointing at `examples/hello-world` as the
zero-config quick-start ("cd examples/hello-world && npm install &&
npm run render") for six weeks, but the example itself was never
actually committed — the source tree existed locally but had zero
git history on any branch.

This commits the working example as-is:

- Minimal 25s Remotion sprint-review video (4 animated slides:
  Title → Overview → Stats → Credits)
- Zero API keys, zero Python, zero external services — just
  Remotion + React
- Config-driven content via src/config/sprint-config.ts
- Remotion 4.0.425, matching all current toolkit templates
- Slide components are byte-identical to templates/sprint-review/
  (no drift, no stale copies)

Gitignore already handles node_modules/, out/, and *.mp4 correctly,
so the staged tree is 24 source files only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 22:04:45 +01:00
Conal Mullan 4402e5a550 EXAMPLES: add quick-spot and data-viz-chart moviepy references
Two runnable example projects demonstrating the moviepy patterns
introduced in the previous commit. Both render end-to-end with zero
external assets via `python3 build.py` and serve as the public
references for the moviepy skill.

quick-spot
  15-second ad-style spot. Solid colour backgrounds, PIL-rendered
  text, audio-anchored timeline, optional VO + ducked music mixing.
  Includes VOICEOVER-SCRIPT.md showing how to extend with per-scene
  audio via tools/voiceover.py.

data-viz-chart
  Animated time-series chart from data/star_series.json (real GitHub
  star history). Demonstrates the matplotlib (data) + moviepy
  (trustworthy text) split: matplotlib draws line/fill/axes, moviepy
  composites the title, headline number, and source attribution
  deterministically on top. Cache-aware — re-renders the matplotlib
  step only when the data file changes.

moviepy skill
  Replaces three references to local-only projects/_lib/townhall_video.py
  paths (which were broken for anyone cloning the repo) with pointers
  to the new public examples.

examples/README.md
  Adds both examples to the table, distinguishes Remotion vs moviepy
  examples in the "Using Examples" section.

.gitignore
  Adds examples/*/.text_cache/ and examples/*/chart_anim.mp4 to keep
  auto-generated build artefacts out of git.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 21:39:41 +01:00
Conal Mullan 8ef3fcc517 Lower barrier to entry: all API keys optional, friendlier error messages
Make it clear that videos render with just Node.js installed. Reorganize
.env.example with commented-out defaults, add "Try It Now" quick start
pointing to hello-world example, and replace terse API key errors in all
Python tools with actionable guidance (add key, use alternative, or skip).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:54:17 +00:00
Conal Mullan 0d96c3b764 Add shared component library, unified commands, and examples
Major changes:
- Shared lib/ with reusable components (AnimatedBackground, SlideTransition,
  Label, Vignette, LogoWatermark, SplitScreen, NarratorPiP)
- Theme system (ThemeProvider, useTheme) in lib/theme/
- Multi-session project system with project.json schema
- Brand loader utility and brand.ts generation

Commands:
- /video - unified project management (replaced /new-video, /new-sprint-video)
- /brand - brand profiles (replaced /new-brand)
- /template - list templates
- /skills - list/create skills (renamed from /skill to avoid Claude Code conflict)
- /contribute - guided contribution workflow

Infrastructure:
- examples/ directory for shareable showcase projects
- CONTRIBUTORS.md for recognition
- FEEDBACK.md for capturing improvements
- Evolution narrative in all commands

Fix:
- Renamed /skill to /skills - naming collision with built-in Skill tool was
  silently preventing ALL custom commands from loading

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 19:03:56 +00:00