os.system(f"manimgl {__file__} ClassName") interpolates the script's own
path into a shell string. These templates are meant to be copied and
renamed per-scene by an agent, so a scene/folder name containing shell
metacharacters is a real injection path, not just malformed input.
Switched to subprocess.run() with an argument list (no shell=True), so
there's nothing left for a shell to interpret regardless of what the
path contains. Same fix applied in both duplicate locations
(.claude/skills and .agents/skills) since the files are identical.
Reviewed scripts/lib/tts.mjs's child_process usage as part of the same
report -- not included in this PR, it already passes args as a real
array with no shell:true anywhere in the call chain, so it isn't
actually exploitable.
Add an Azure AI Speech transcription tool. It is opt-in: when
AZURE_SPEECH_KEY is configured the agent may prefer it for cloud STT,
while the local faster-whisper `transcriber` stays the default offline
path. Shared pipeline manifests are intentionally left unchanged, so no
default provider selection is altered for existing users.
- tools/analysis/azure_stt.py: new `azure_stt` tool (capability=analysis,
provider=azure) calling the Fast Transcription REST API. The local file
is uploaded via multipart and transcribed synchronously with word-level
timestamps and optional diarization — no Blob storage or async polling.
Output schema mirrors `transcriber` exactly, so it is a drop-in for
`subtitle_gen` and other transcript consumers. Follows the existing
provider-tool conventions (env-var status check, `_transcribe` helper,
cost_usd/model on the result, fallback="transcriber").
- Auto-discovered by the registry; no registry or selector changes.
- tests/tools/test_azure_stt.py: contract, discovery, status, response
mapping, execute guardrails, and a mocked-network success path (no live
API calls).
- .agents/skills + .claude/skills: azure-speech-to-text Layer-3 skill.
- docs/PROVIDERS.md: Azure AI Speech setup, API notes, and pricing.
- .env.example, skills/INDEX.md, AGENT_GUIDE.md: document the optional
cloud STT path alongside the default whisper transcriber.
Add gemini_omni_video, a native Gemini API provider wrapping
gemini-omni-flash-preview via the Interactions API. Text-to-video,
image/reference-to-video with <FIRST_FRAME>/<IMAGE_REF_N> prompt tags,
and stateful edit_video turns via previous_interaction_id — the only
provider in the fleet that can refine a clip without regenerating it.
Reuses the existing GOOGLE_API_KEY / GEMINI_API_KEY, so one Google key
now unlocks images, TTS, and video.
- New Layer 3 skill .agents/skills/gemini-omni (prompting, edit-loop
rules, tag/timecode syntax, preview limits) sourced from official
Google docs; linked via agent_skills and the AGENT_GUIDE Layer 3 map
- ai-video-gen gains the Gemini API gateway row + editing pointer
- veo_video/sora_video fallback lists and video_selector agent_skills
reference the new provider; quality_score 0.85 with rationale
- Contract tests: registry discovery, selector routing, status from
env keys, uri + inline delivery, edit turns, typed image parts,
store=false editability, cost clamp
Licensing (finding 1):
- Mocap library is now 100% CMU-sourced (free for any use). Replaced the 3
Meta/FAIR clips with CMU equivalents: wave=141_16, shuffle=77_29 (creep);
dropped the un-CMU "dab", added twist=141_12. Deleted the 4 committed FAIR
BVHs (dab/jumping/wave_hello/zombie).
- Ship Patrick Hand's SIL OFL license (assets/OFL.txt) beside the bundled font
— OFL permits embedding/redistribution; this is the required attribution.
- Add THIRD_PARTY_NOTICES.md (Patrick Hand OFL + CMU) and rewrite mocap/NOTE.md
to drop the "verify before commercial use" caveat (no longer applicable).
Stale clip names (finding 2):
- Update the /ink-art command files (.claude/.github/.cursor/.codex),
character-design-director, and the creative skills to the current catalog
(wave/twist/…), and point to add-motion.mjs.
- ink-puppet.js: console.warn on an unknown clip name instead of silent dead-time.
Examples (finding 3):
- Remove broken standalone reel.html/momentum.html (they referenced a missing
ink-theater.js and momentum shipped the subset font the fix warns against).
- Keep mocap-figure/ as the canonical self-contained, lintable example; refresh
its bundled clips.js/ink-puppet.js; add examples/README.md with the lint path.
Makes the doodle-animation capability findable instead of hidden.
Routing (OpenMontage-internal):
- AGENT_GUIDE: Style Playbooks gets an ink-sketch row + a 'hand-drawn doodle'
routing note (it's a style + engine on the animation / character-animation
pipelines, NOT a new pipeline).
- animation/idea-director + character-animation/character-design-director point
to the Ink Theater / Ink Puppet skills for hand-drawn character briefs.
Cross-agent slash commands (/ink-art, /animated-drawing) for Claude Code,
Copilot, Cursor, and Codex — thin pointers to the canonical skills so they stay
in sync. /ink-art = create a vector doodle from scratch (Ink Theater + Ink
Puppet mocap); /animated-drawing = animate a SUPPLIED drawing via Meta
AnimatedDrawings (raster). New skills/creative/animated-drawing.md documents the
Path A setup/run/limits. Codex prompts are user-home only — .codex/prompts/README
explains the copy/symlink step.
.claude/commands/*.md (Claude Code)
.github/prompts/*.prompt.md (Copilot)
.cursor/commands/*.md (Cursor)
.codex/prompts/*.md + README (Codex; copy to ~/.codex/prompts)
The skill SKILL.md files are hardlinked across .agents/skills/ and
.claude/skills/ (same inode, two paths), but git had committed divergent
blobs: the .agents/ copies carried an "Extended reference: AGENTS.md"
note that the .claude/ copies lacked. Because one physical file cannot
match two different blobs, the working tree was permanently dirty on the
three .claude/skills paths.
Stage the .claude copies so both paths commit identical content (with the
AGENTS.md reference note, the fuller intended version). Restores a clean
git status and keeps it clean across checkouts.
Affected skills: flux-best-practices, vercel-composition-patterns,
vercel-react-best-practices.
Seedance 2.0 is now routed as the top-ranked video generator whenever a
premium gateway is available. Touches the tool layer, scoring engine,
cinematic pipeline, and both skill layers so discovery works from every
entry point.
- tools/video/seedance_video: BETA stability, quality_score=0.95, add
reference_to_video operation plus 9 img + 3 vid + 3 audio ceilings,
fix pre-existing upload_image_fal import
- tools/base_tool: surface optional quality_score / success_rate /
latency fields in get_info so the scorer can read them
- lib/scoring: fix reliability enum-vs-string bug that was pinning every
available tool to 0.0, switch to overlap coefficient so rich best_for
descriptions aren't penalized, add premium-cinematic feature bonus
- pipeline_defs/cinematic + cinematic asset-director: add pixabay_music
and freesound_music, restore pixabay-first music default
- cinematic compose-director: mandatory Remotion preflight at stage entry
- New Layer 3 .agents/skills/seedance-2-0/SKILL.md (8-part prompt
structure, multi-shot, lip-sync, reference-to-video, provider landscape)
- New Layer 2 skills/creative/prompting/seedance-prompting.md
- Update ai-video-gen, video-gen-prompting, AGENT_GUIDE, INDEX to flag
Seedance 2.0 as the preferred premium default and make the skill
discoverable from every routing path