`tools/dewatermark.py --setup` aborted with `NameError: get_runpod_config` before
doing any work — the helper is defined nowhere in the repo. Replaced with the
`load_dotenv()` + `os.getenv("RUNPOD_API_KEY")` pattern `tools/upscale.py` already
uses in the same function. Verified: setup now runs and finds the existing
template/endpoint.
Follow-up cleanup to the _migrate_common refactor (#85):
- `_migrate_common.load_mapping` was a stub returning raw JSON, so any caller
would KeyError on `mapping["skip_commands"]`. Nothing hit it because both
scripts shadowed it with a local copy. Promoted the real normalizing version
(handles `None`, coerces skip lists to sets) and dropped both local copies.
- Dropped the duplicate `find_repo_root` from both scripts; the shared one is
equivalent and has a better error message.
- Dropped the unused `yaml_quote` import from migrate_to_kiro.py.
Verified behaviour-neutral: `migrate_to_codex.py --force` and
`migrate_to_kiro.py --force` produce byte-identical output trees before and after.
New Lint Python workflow gates on undefined names (F821/F811/F822/F823) across
scripts/ and tools/. Scoped to rules where a hit is a real defect — the repo has
~800 unused-import and unused-local warnings that are not worth gating on.
Confirmed against the tagged v0.20.0 tree, where it reports 26 errors including
both `write_text` sites that broke the Codex and Kiro migrations.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both migration scripts crash with NameError as soon as they do any real
work. Running either one (without --dry-run) fails at the first call site:
File "scripts/migrate_to_codex.py", line 436, in main
install_command_wrappers(
File "scripts/migrate_to_codex.py", line 332, in install_command_wrappers
write_text(
NameError: name 'write_text' is not defined
The extraction in 18de2b8 moved ensure_clean_dir/copy_tree/remove_dir into
scripts/_migrate_common.py, but write_text was deleted without being moved
there and without being added to either import list. It is still called by
install_overview_skill() and install_command_wrappers() in both scripts,
which are on the main (non-dry-run) install path, so the migration always
aborts after AGENTS.md / steering sync and before a single skill is written.
The same commit also removed the `def copy_tree(...)` and `def remove_dir(...)`
headers while leaving their bodies behind, so eleven statements referencing
undefined names (shutil, src, dest, path, dry_run) are now stranded after
`return results` inside load_skill_specs() in each script.
- restore write_text() in _migrate_common.py, byte-identical to the
pre-refactor implementation, and import it in both scripts
- delete the two orphaned function bodies
Verified on a clean checkout: before the patch both scripts raise NameError;
after it `migrate_to_codex.py --force` installs 27 skills under
~/.codex/skills and `migrate_to_kiro.py --force` installs them under
~/.kiro/skills. `pyflakes scripts/` reports no undefined names afterwards.
Review fixes on top of the #58 extraction, all introduced by the move rather
than present in either source file:
- find_repo_root was defined twice. The second won and matched what both
migrate_to_codex.py and migrate_to_kiro.py already did; the first was neither
script's implementation — it walked cwd for CLAUDE.md instead of __file__ for
_internal/toolkit-registry.json, and raised RuntimeError instead of SystemExit.
Dead as written, but silently wrong the moment anything reorders the file.
- Stripped a UTF-8 BOM. Neither sibling script has one.
- Added `from __future__ import annotations`, which both source files carry and
every other script in scripts/ does.
Behaviour is unchanged: `--dry-run` output for both scripts is byte-identical to
main (32 and 31 lines), and --help and --reset --dry-run both still work.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
scripts/bump_remotion.py rewrites every remotion/@remotion/* pin under
templates/, examples/, showcase/, tests/ to an exact version, refreshes
lockfiles, optionally smoke-renders frame 0 per project (--smoke), runs
the render-baseline A/B, and emits a markdown summary for the PR body.
versions.md documents the flow. .github/dependabot.yml opens one grouped
monthly Remotion PR across the same directories, gated by the
render-baseline workflow.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* FEAT: render-baseline harness — A/B render diff across Remotion bumps (#23 part 2)
tests/render-baseline/: fixed 6-block composition (interpolate/spring,
Sequence+text in a bundled font, OffthreadVideo on a committed testsrc
clip, Audio, TransitionSeries with lib/transitions glitch+zoomBlur,
lib/components) with duration from calculateMetadata. No system fonts,
no network, no Math.random.
scripts/render-baseline.mjs: render <label> (bundle once, one still per
block at --scale=0.25 --gl=swangle), diff <a> <b> (pixelmatch perceptual
+ exact counts, diff PNGs, report.md/json, exit 1 over --threshold,
default 0), install <version>, and ab <version> for local one-shot use.
.github/workflows/render-baseline.yml: on PRs touching package.json
under templates/examples/showcase, tests/render-baseline, lib/ or the
script — renders base-branch pin and PR pin on the same runner, diffs,
comments the table, uploads stills, fails on any difference so a human
looks. workflow_dispatch takes a candidate version.
Verified locally: same-version render is byte-identical (0 px on all
six); 4.0.425 → 4.0.518 (93 patches) is also 0 px on all six.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* FIX: render-baseline workflow falls back to PR pin when base branch lacks the harness
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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>
* 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>
- Read toolkit name from _internal/toolkit-registry.json with fallback to
repo_root.name. Descriptions now correctly say "in claude-code-video-toolkit"
regardless of the local checkout directory.
- Remove the openclaw-video-toolkit skip_skills entry that never fired
(.claude/skills/ is the only path scanned by design). Brief comment in
load_skill_specs explains why so future readers don't "fix" the missing scan.