* 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>
Mirror scripts/migrate_to_codex.py for Kiro CLI. Kiro shares Claude
Code's SKILL.md format and $ARGUMENTS convention, so toolkit skills
copy verbatim into ~/.kiro/skills and each .claude/commands/*.md gets
a wrapper skill invoked as the same /video, /setup, ... slash command,
pointing at the original file as source of truth. CLAUDE.md is
generated into .kiro/steering/ inside a managed marker block.
Skills install globally with the toolkit's absolute path pinned in
each wrapper, preserving Claude Code parity: commands work from any
directory, since Kiro does not walk up the tree to find workspace
.kiro/ the way Claude Code finds .claude/. --workspace-skills opts
into a repo-local install.
TESTING: verified end to end in kiro-cli chat — all 26 skills load
from the repo root and subdirectories, tab completion resolves /video,
and the /video, /scene-review, /generate-voiceover, and /setup
wrappers follow their original workflows through project creation and
a local render. --force is idempotent; --reset removes only toolkit
skills; steering preserves manual content; full cycle passes on
macOS (py3.12) and Amazon Linux 2 (py3.7).
Co-authored-by: Homeo <homeo@amazon.com>
Co-authored-by: Conal Mullan <cmullan@digitalsamba.com>
* CHORE: bookkeeping catch-up for v0.18.0 — registry, roadmap, changelog
Registry gains the entries that had drifted since April: ai-engineering-review
template, digital-samba-ai-engineering brand, align_captions tool, and the
quick-spot / data-viz-chart / ds-crt-stinger / sky-blue-short examples;
the-space-between is marked showcase-only (no source dir). Version → 0.18.0.
ROADMAP current-status and metrics refreshed (5 templates, 12 skills, 22
tools, 7 examples), modal-setup doc ticked, generator/publishing sections
added. CHANGELOG fills in v0.15.0 → v0.18.0 (it had stopped at v0.14.2).
README templates list adds ai-engineering-review.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019s6SvNiz9a8XpD8r2cQTiq
* CHORE: keep ai-engineering-review template and brand unlisted — not ready for public use
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019s6SvNiz9a8XpD8r2cQTiq
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* FIX: point Remotion skills sync at upstream's new skills/remotion-best-practices layout
The weekly sync workflow has failed every run since 2026-07-13 because
remotion-dev/skills split its single skills/remotion directory into one
skill per topic. remotion-best-practices is the router skill that embeds
every other skill as a REFERENCE.md sub-directory, so syncing just that
directory yields the complete, self-contained knowledge set with a single
SKILL.md. The workflow now fails loudly (with a directory listing) if the
upstream layout moves again, and carries the upstream skill version in
the PR title. Docs and registry updated to match.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019s6SvNiz9a8XpD8r2cQTiq
* Sync official Remotion skills (upstream v4.0.518, 7a3d0ca) — new per-topic layout
First sync from skills/remotion-best-practices. Adds maps, captions,
render, saas, studio, docs, upgrade and interactivity sub-skills; markup
guidance moves from rules/ to remotion-markup/. Upstream still teaches
@remotion/media — the toolkit deliberately stays on <OffthreadVideo>
(see CLAUDE.md Media section), which is unchanged from the prior sync.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019s6SvNiz9a8XpD8r2cQTiq
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The other toolkit docs cover mechanics (timing, transitions, components); this
covers narrative — what order to tell a sprint in, and how to frame it. Argues
that the default "here's what we shipped, in ticket order" format wastes the
material when a sprint has a story in it.
Documents three patterns:
- Discovery Story — a six-beat arc (context, first fix, workaround, turning
point, answer, roadmap) for sprints where the journey beats the deliverables
- Version Clash Title — divergent version numbers on the title card with ">"
separators, so fragmentation reads at a glance
- Bridge Framing — presenting a deliverable that works today but isn't the
long-term answer, honestly, across narration, decisions slide and roadmap
Version Clash is documented as a spec, not a feature: sprint-review and
sprint-review-v2 both build `Version ${info.version}` unconditionally, so the
pattern needs a TitleSlide change first. The doc quotes the current code and
gives the conditional rather than implying the capability already exists.
Worked example is illustrative and domain-neutral.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019s6SvNiz9a8XpD8r2cQTiq
* Added 60dB integration
* FIX: make 60db TTS synthesize transport work against the live API
The original integration coded to 60db's documented /tts-synthesize contract
(single JSON object with `audio_base64` in the requested container format).
In production the endpoint instead streams newline-delimited JSON of raw
16-bit mono PCM (Content-Type: application/x-ndjson) with a trailing
`{metadata}` line, so the default voiceover path failed with "Invalid JSON
response".
Changes (tools/sixtydb_tts.py):
- Rewrite _synthesize_rest to consume the NDJSON PCM stream, while still
accepting the documented single-JSON shape if 60db ships it.
- Add _finalize_audio: sniff bytes for an audio container (mp3/wav/ogg/flac)
and write/transcode as-is, else wrap raw PCM as WAV and transcode to the
requested --output-format via ffmpeg.
- Add _derive_pcm_sample_rate: infer the rate from byte-count and the
metadata audio_sec (snap to nearest standard rate) instead of hardcoding.
- Surface 60db metadata warnings; route _synthesize_stream through the same
PCM-aware finalizer and flag that /tts-stream currently 500s upstream.
Verified live: sixtydb_tts.py and `voiceover.py --provider 60db --scene-dir`
both produce valid 48kHz MP3s for English and Hindi.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* FIX: apply pacing QC (wpm/--max-wpm) to the 60db provider path
Rebase integration: pacing QC landed on main after this branch was cut;
elevenlabs and qwen3 paths report wpm/pacing and honor --max-wpm, but the
60db path bypassed it. Wire _apply_pacing_qc into generate_single_audio_60db
and pass max_wpm at both call sites.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MKbS3m7TXrfYjE7gDVEpnV
---------
Co-authored-by: manishEMS47 <manish.prasad@engineermaster.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat: add YouTube upload pipeline (tools/youtube_upload.py + /publish)
Adds the toolkit's first publishing capability: upload a rendered video to
YouTube via the Data API v3.
- tools/youtube_upload.py: OAuth 2.0 installed-app flow with silent token
refresh (per-account cache), resumable upload with exponential-backoff
retry, optional thumbnail/captions/playlist, and private/unlisted/public
or scheduled (publishAt) visibility. Flags for --auth, --dry-run, --json-out.
- /publish command: guided workflow that auto-fills title/description/tags
from a project's project.json, dry-runs, uploads, and writes back the URL.
- config.py: get_youtube_client_secrets_file(), get_youtube_token_dir().
- docs/youtube-upload.md: Google Cloud Console walkthrough, quota math, and
the unverified-app private-lock / 7-day token gotchas.
- Wiring: requirements (google-api-python-client/auth-oauthlib/auth-httplib2),
registry entries, CLAUDE.md publishing section, .env.example, and a
.gitignore rule for the _internal/.youtube/ token cache.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs: soften the unaudited-project private-lock warning to match reality
The pre-upload warning and docs asserted that unverified apps force every
upload to private. Verified empirically that first-party uploads (own Cloud
project + own channel + own account) publish public/scheduled fine without an
audit — the lock mainly targets third-party apps uploading to other channels.
Rewords the runtime warning, module comment, docs/youtube-upload.md, CLAUDE.md,
and .env.example to say public uploads MAY be locked (chiefly cross-account),
and to treat the tool's actual returned privacyStatus as the source of truth.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Make /publish channel-agnostic for public use
Drop the SUPERINTELLIGENCE-specific category default and the
schedule-by-default cadence from the /publish command:
- category: neutral default "22" (People & Blogs) with override examples
- privacy: default to `private` (safe least-surprise default) instead of
auto-scheduling a public go-live
Channel-specific defaults (playlist, public-pairs cadence, Studio
checklist) stay in the local working copy, out of the public toolkit.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Robert Strobl <rs@digitalsamba.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* 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>
Cloned voices inherit speaking pace from their reference audio, and
regenerating at lower temperature does not correct it — a short, snappy
reference reliably produces 170-210 wpm narration on every take (observed
across 11 consecutive regens). Measuring pace and correcting it
deterministically beats sampling.
- New tools/pacing.py: wpm measurement (pause-marker/SSML aware),
fast/slow/ok labels, and a pitch-preserving ffmpeg atempo clamp
(floor 0.85x so stretching never becomes audible)
- voiceover.py and qwen3_tts.py results now always include wpm + pacing;
human mode prints per-scene pace notes and warnings
- New --max-wpm flag on both tools (all providers, single/batch/scene-dir)
slows rushed takes in place and reports pace_adjusted in JSON
- /voice-clone now validates reference audio before saving (duration +
word-count gates) and teaches that the clone copies the reference's pace
- CLAUDE.md: pacing row in the TTS drift table; registry: pacingQC option
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* FEAT: add Ideogram 4 text-to-image (best-in-class in-image text rendering)
New `tools/ideogram4.py` generates images via Ideogram's hosted v4 API —
its strength is legible baked-in text (title cards, thumbnails, CTAs, quote
cards, in-scene signage), exact hex color palettes, and bounding-box layout,
where FLUX.2 and LTX-2 both garble text.
- Thin multipart wrapper over POST /v1/ideogram-v4/generate (Api-Key header).
Mutually-exclusive --json (structured json_prompt, the quality path) and
--prompt (text_prompt, server-side magic prompt). --brand injects brand.json
hex colors into the caption palette; --speed FLASH/TURBO/DEFAULT/QUALITY.
- New `ideogram4` skill (.claude/skills/ideogram4/) teaching the structured
JSON caption format — Claude acts as the magic-prompt expander (beats the
weaker free hosted one). SKILL.md + prompting.md + examples.md.
- Hosted paid API chosen over self-hosting: the v4 weights are non-commercial,
the API includes a commercial license, and the API's json_prompt preserves
the full prompting-skill value (~$0.03-0.09/image).
- get_ideogram_api_key() in tools/config.py; registry entries for skill+tool.
- CLAUDE.md: FLUX.2-vs-Ideogram-4 decision guidance (baked-in text vs.
background-for-Remotion-overlay).
Tested live: json_prompt title card and text_prompt thumbnail both render with
crisp legible text; resolution 2048x2048 accepted. Closes#25.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* DOCS: refresh ideogram4 registry notes (tool built + live-tested)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ships the lovis93/crt-animation-terminal LoRA baked into the Modal image.
Pipeline rebuilds only when the requested LoRA differs from the currently
loaded one, so repeat calls skip the ~60s reload. Client CLI gains a
--lora flag with LORA_PRESETS that auto-prepend the trigger token and
switch geometry/negative-prompt defaults to what the LoRA expects.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps version in _internal/toolkit-registry.json and prepends the
v0.14.2 entry to _internal/CHANGELOG.md. No code changes — the
release-worthy changes shipped in the preceding commits:
c6df139 README: add q2 townhall longarm-ad and stars to examples
9a57fdf SKILLS: add moviepy skill, audio-anchored timelines, LTX-2 cameo pattern
4402e5a EXAMPLES: add quick-spot and data-viz-chart moviepy references
2a638fe EXAMPLE: add hello-world — the quick-start the README already promised
6f94523 DEPS: declare moviepy/Pillow/matplotlib in tools/requirements.txt
3057ab8 FIX: cross-platform font loading in moviepy examples
Theme: Python-native video composition alongside Remotion. New moviepy
skill with the "trustworthy text" framing for AI-generated video, two
runnable moviepy examples (quick-spot, data-viz-chart), finally-committed
hello-world Remotion example the README has been pointing at since Feb,
central dependency declaration for Pillow/moviepy/matplotlib in
tools/requirements.txt, and cross-platform font loading in both new
examples.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three coordinated additions promoting lessons from the q2-townhall projects
to toolkit-level guidance:
- New moviepy skill covering deterministic text overlay on AI-generated
video (LTX-2, SadTalker) — the canonical post-process for any genre
where text must be trustworthy (news, trailers, lower thirds, social
captions). Includes the PIL workaround for moviepy 2.x's TextClip
ascender-clipping bug, plus common composite recipes.
- ltx2 skill: add "Stylized Character Cameo" use case as a SadTalker
alternative for non-photoreal faces (fantasy characters, heavy beards,
masks) where lip-sync precision matters less than motion + atmosphere.
- docs/sadtalker.md: add "When NOT to Use" section pointing to LTX-2 for
the same cases.
- CLAUDE.md: add "Audio-Anchored Timelines" section to the timing guide
as a prevention-first complement to the existing reactive sync_timing.py
flow. Especially useful for moviepy build.py-style projects.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 20-min subprocess timeout (buffer over ltx2's 15-min cloud timeout)
- Switch to capture_output=True with stderr in error messages
- Validate --prompts-file JSON with helpful error on malformed input
- Clean up .frame-*.png temp files after run completes
- Fix glob pattern to require hyphen separator (prevents 05 matching 050)
- Add chain_video to toolkit-registry.json
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Switch music_gen.py from self-hosted Modal/RunPod to the official ACE-Step
cloud API (acemusic.ai) as the default provider. This gives access to the
XL Turbo 4B model with 5Hz LM thinking mode — significantly better quality
and variety than the self-hosted 2B model, with free API keys and no GPU costs.
New features: --thinking/--no-thinking, --variations, --repaint,
--continuation, --guidance-scale, --infer-method. Modal/RunPod remain as
--cloud modal/runpod fallbacks.
Skill doc updated with vocal gender control and duet patterns discovered
through testing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix hardcoded 1800s Modal container timeout that could kill jobs during
cold starts or moderate-length audio
- Dynamic per-chunk subprocess timeouts scale with audio duration
instead of flat 1800s
- Add pre-flight estimate (chunks, time, cost) before job submission
- Add chunk-level progress logging to Modal app
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New /setup command: interactive 6-phase onboarding wizard for new users
(prerequisites, cloud GPU provider, R2 file transfer, tool deployment,
voice config, verification)
- New verify_setup.py: checks all prerequisites, env vars, deployed apps,
and optionally runs smoke tests (--test flag)
- Migrate dewatermark.py to cloud_gpu.py: replace ~400 lines of inline
RunPod code with shared abstractions, add --cloud runpod|modal flag
- Add dewatermark to Modal env vars and GPU cost tables in cloud_gpu.py
- Rewrite .env.example: all 22 env vars organized by service, Modal
section added, references /setup
- Update README, CLAUDE.md, getting-started.md, video.md to reference
/setup as the primary onboarding path
- Register setup command and verify_setup tool in toolkit-registry.json
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Modal provider section to Phase 3 with checklist of completed and
remaining items. Add modal skill to status table as beta.
Remaining: docs/modal-setup.md, --setup --cloud modal automation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
RunPod has been unreliable — Modal provides faster cold starts and
more robust infrastructure. This adds Modal support for qwen3_tts
and flux2 behind a new --cloud runpod|modal flag (default: runpod).
New files:
- tools/cloud_gpu.py: shared provider abstraction with cost estimation
- docker/modal-qwen3-tts/app.py: Modal deployment for Qwen3-TTS
- docker/modal-flux2/app.py: Modal deployment for FLUX.2 Klein 4B
Modified:
- tools/qwen3_tts.py: --cloud flag, routes through cloud_gpu
- tools/flux2.py: --cloud flag, routes through cloud_gpu
- tools/config.py: Modal config getters
- _internal/toolkit-registry.json: Modal provider section
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Covers: caption writing dimensions, lyrics formatting with structure/vocal
tags, scene preset selection guide, video timing integration, brand
consistency patterns, cover/extract workflows, and technical reference.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Integrates ACE-Step 1.5, an open-source music generation model, as a free
alternative to ElevenLabs Music with precise BPM/key/duration control,
vocal support, and stem extraction capabilities.
- tools/music_gen.py: CLI tool with text2music, cover, stem extraction,
8 scene presets, brand integration, and RunPod --setup
- docker/runpod-acestep/: Dockerfile (CUDA 12.8, torch 2.10, baked weights)
and RunPod serverless handler using ACE-Step inference API
- Registry updated with music_gen tool and acestep cloud endpoint
RunPod end-to-end test pending GPU availability.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All 6 RunPod tools now auto-cancel jobs stuck in queue >5 min and
cancel orphaned jobs on polling timeout, preventing runaway billing
from GPU unavailability. Fixed R2 upload support in flux2 and
image_edit clients. Switched flux2 default GPU to AMPERE_24 with
ADA_24 fallback. Added RunPod API reference to skill docs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New tools/flux2.py: text-to-image, image editing, multi-image compositing
- 8 scene presets for video production (title-bg, problem, solution, etc.)
- Brand-aware generation reads brand.json colors into prompts
- Docker image with baked model weights (ghcr.io/conalmullan/video-toolkit-flux2)
- Rebuilt qwen3-tts Docker image with baked models
- "The Space Between" showcase video (all AI-generated)
- Updated README, registry, and changelog
Closes#6
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New tool: tools/sync_timing.py — syncs scene durationSeconds in Remotion
config with actual audio durations after TTS generation. Auto-detects
template type, matches audio to scenes via 3-pass algorithm (audioFile →
index → name), shows comparison table, and applies updates in-place.
CLAUDE.md reduced from 861 → 480 lines (44%) by removing catalog data
duplicated in toolkit-registry.json (skills, commands, components,
transitions, presets, Docker images) and adding cross-references.
All workflow guidance, timing knowledge, and code patterns retained.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Align changelog, registry, and roadmap with all changes since v0.9.3:
Qwen3-TTS, sprint-review-v2, hello-world example, runpod skill,
FilmGrain component, voice-clone command, onboarding improvements,
and Remotion skills sync.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pass temperature and top_p kwargs through the full stack (handler.py →
qwen3_tts.py → voiceover.py) to control voice expressiveness and sampling.
Fix docker-build.yml multi-line JSON breaking $GITHUB_OUTPUT by using jq -sc.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add named tone presets (warm, professional, excited, calm, etc.) with
--tone flag and --list-tones for both qwen3_tts.py and voiceover.py
- Add per-scene instruct overrides via [tone: X] frontmatter in .txt files
- Add /voice-clone command for guided clone setup workflow
- Add brand voice config loading (speaker, tone, clone from voice.json)
- Guard against tone/instruct with cloned voice (clone mode ignores instruct)
- Fix PR #3 code quality issues (unused import, unused variable, empty except)
- Update commands, docs, and CLAUDE.md with tone examples
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds Qwen3-TTS as a free, self-hosted alternative to ElevenLabs for
voiceover generation via RunPod serverless. Supports 9 built-in speakers,
natural-language emotion control, and voice cloning from reference audio.
- Docker image (docker/runpod-qwen3-tts/) with RunPod handler
- CLI tool (tools/qwen3_tts.py) with --setup, --list-voices, generation
- voiceover.py: --provider qwen3 support with lazy ElevenLabs imports
- GitHub Actions workflow for automated Docker image builds
- Config, registry, docs, and generate-voiceover command updated
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- voiceover.py: --scene-dir processes .txt files, --concat for SadTalker
- sprint-review: audioFile field on DemoConfig, info, overview, summary
- SprintReview.tsx: per-scene <Audio> elements with backward compatibility
- /generate-voiceover: detects scene scripts, offers per-scene as default
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- New animated isometric grid decoration for video corners
- Parameterized colors (defaults to theme primary/backgroundDark)
- Configurable corner position, opacity, scale
- Wave animation with ripple effect
- Added to sprint-review template as optional feature
- Documented in template README with config example
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New features:
- SadTalker tool for generating talking head videos from portrait + audio
- Auto-timeout calculation based on audio duration
- Job recovery with --retrieve flag for timed-out jobs
- Comprehensive NarratorPiP integration documentation
Key patterns documented:
- Use --preprocess full to preserve image dimensions
- Provide 16:9 images for NarratorPiP compatibility
- Use --still --expression-scale 0.8 for professional results
Updated:
- NarratorPiP component now stable (works with SadTalker)
- toolkit-registry.json with SadTalker tool and RunPod endpoint
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add comprehensive docs/sadtalker.md with NarratorPiP workflow
- Document critical patterns: 16:9 image prep, --preprocess full
- Add auto-timeout calculation based on audio duration
- Add --retrieve flag for job recovery after client timeout
- Update NarratorPiP component with objectFit: contain
- Track learnings in BACKLOG.md for future improvements
Key insight: Always use --preprocess full to preserve image
dimensions for video overlays. Let users crop their own images
for best face framing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Track future task to move GPU worker images from personal
(ghcr.io/conalmullan/) to org namespace (ghcr.io/digitalsamba/)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Transitions library was already merged to main. Cleaned up:
- Removed "In Progress" section for experiment/transitions
- Deleted experiment/transitions branch (already merged)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>