- Rewrite _absolute_insertion_point() to walk physical playlist children
instead of using broken prop_offset calculation
- Fix ducking window separator from ':' to '..' for correct timecode parsing
- Add 3 regression tests for --at insertion on non-empty tracks
- Update README: mark melt/ffmpeg as required dependencies, add REPL
command reference with example session
- Update SKILL.md: add complete REPL command list, two-step workflow docs
- Sync SKILL.md to root mirror
Cover single clip, multi-segment with blanks, and empty timeline cases
to verify tractor/background/black producer out= is set correctly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
extra_args could pass vcodec=..., acodec=..., or -consumer to override
the validated codec parameters. Add _validate_extra_args() that rejects
any argument starting with these prefixes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When an AI agent constructs CLI commands, it may pass arbitrary strings as
codec parameters — either through prompt injection, hallucination, or
processing untrusted input. Since codec values are passed directly to
melt/ffmpeg subprocesses, unvalidated input is an injection risk.
Fix: add ALLOWED_VCODECS / ALLOWED_ACODECS allowlists to both kdenlive
and shotcut melt_backend.py. All codec parameters are validated before
reaching subprocess.run(). Unknown codecs raise ValueError with a list
of valid options.
Also add SECURITY.md documenting the project's threat model (AI agents
as CLI callers), attack surfaces, reporting process, and security
guidelines for harness developers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Closes#51
The root cause: all 10 harnesses used bare `open("w") + json.dump()` for
session saves. `open("w")` truncates the file before any lock can be
acquired, so concurrent writes silently corrupt or lose data.
Fix: add `_locked_save_json()` to each session.py that opens with "r+"
(no truncation), acquires fcntl.LOCK_EX, then truncates inside the lock.
Falls back gracefully on Windows where fcntl is unavailable.
Also:
- Update HARNESS.md with session file locking guidance (per maintainer
request on PR #52)
- Add concurrent write tests (4 threads × 50 writes) to verify the fix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When clips are added to the timeline, the MLT tractor element is created
with out="00:00:00.000" and never updated. The background track defaults to
out="04:00:00.000" (a Shotcut convention). Without an explicit tractor out,
melt falls back to the longest track and renders a ~4-hour file instead of
the actual content duration.
Fix: calculate the real content duration from all non-background playlists
(summing entry in/out spans and blank lengths), then set out= on the tractor,
background playlist entry, and black producer before writing the temp MLT.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fill in the previously empty command tables with actual commands
extracted from each CLI's Click decorators. All 11 harnesses now
have complete command documentation in their SKILL.md files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move skills/SKILL.md from the harness root into
cli_anything/<software>/skills/SKILL.md so it is installed alongside the
package via pip. Add package_data to all 11 setup.py files. Make
ReplSkin auto-detect the skill file relative to its own __file__
location, removing the need for an explicit skill_path argument.
Update HARNESS.md, cli-anything.md, plugin README, and main README.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Standardize skill file naming from <software>_SKILL.md to SKILL.md across
all 11 harnesses. Update skill_generator.py, HARNESS.md, repl_skin.py,
cli-anything.md, and plugin README.md to reference the new path. Add
SKILL.md generation section to main README.md and mark roadmap item done.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
## Changes
### 1. Display skill path in CLI header (repl_skin.py)
- Added `skill_path` parameter to ReplSkin class
- Banner now displays skill path when provided: `◇ Skill: skills/<software>_SKILL.md`
- This enables AI agents to discover where to read the skill documentation
### 2. Generate SKILL.md files for all 11 existing CLI harnesses
- anygen/agent-harness/skills/anygen_SKILL.md
- audacity/agent-harness/skills/audacity_SKILL.md
- blender/agent-harness/skills/blender_SKILL.md
- drawio/agent-harness/skills/drawio_SKILL.md
- gimp/agent-harness/skills/gimp_SKILL.md
- inkscape/agent-harness/skills/inkscape_SKILL.md
- kdenlive/agent-harness/skills/kdenlive_SKILL.md
- libreoffice/agent-harness/skills/libreoffice_SKILL.md
- obs-studio/agent-harness/skills/obs_studio_SKILL.md
- shotcut/agent-harness/skills/shotcut_SKILL.md
- zoom/agent-harness/skills/zoom_SKILL.md
### 3. Update HARNESS.md with skill path guidance
- Updated Phase 3 (REPL section) to show skill_path parameter usage
- Added "Display Skill Path in CLI Banner" section in Phase 6.5
### 4. Fix skill_generator.py syntax error
- Fixed list comprehension indentation on line 80-81
Addresses maintainer feedback from PR #47 comment:
- "displaying the skill path on the cli header so that agents can know where to read it"
- "generate skill.md files for all existing CLIs we have in the repo"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixed 8 setup.py files that had placeholder URLs:
- Changed 'yourusername' to 'HKUDS'
- Changed repo name to 'CLI-Anything'
This fixes broken metadata when packages are published to PyPI.
Add -s/--save flag to automatically save project after each mutation
command. This fixes the issue where one-shot commands don't persist
changes because each command runs in a new process with a fresh session.
Usage:
shotcut-cli --project edit.mlt -s timeline add-track --type video
# Now auto-saves after adding the track
Without -s flag, behavior is unchanged (explicit save required).