Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions shotcut/agent-harness/cli_anything/shotcut/shotcut_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ def wrapper(*args, **kwargs):


_repl_mode = False
_auto_save = False


# ============================================================================
Expand All @@ -124,17 +125,23 @@ def wrapper(*args, **kwargs):
@click.option("--json", "json_mode", is_flag=True, help="Output in JSON format")
@click.option("--session", "session_id", default=None, help="Session ID to use/resume")
@click.option("--project", "project_path", default=None, help="Open a project file")
@click.option("-s", "--save", "auto_save", is_flag=True,
help="Auto-save project after each mutation command (one-shot mode)")
@click.pass_context
def cli(ctx, json_mode, session_id, project_path):
def cli(ctx, json_mode, session_id, project_path, auto_save):
"""Shotcut CLI — Video editing from the command line.

A stateful CLI for manipulating Shotcut/MLT video projects.
Designed for AI agents and power users.

Run without a subcommand to enter interactive REPL mode.

Use -s/--save to automatically save changes after each mutation command.
This is useful in one-shot mode where each command runs in a new process.
"""
global _json_output, _session
global _json_output, _session, _auto_save
_json_output = json_mode
_auto_save = auto_save

if session_id:
_session = Session(session_id)
Expand All @@ -144,10 +151,26 @@ def cli(ctx, json_mode, session_id, project_path):
if project_path:
_session.open_project(project_path)

# Register auto-save callback to run after each command
ctx.call_on_close(_auto_save_callback)

if ctx.invoked_subcommand is None:
ctx.invoke(repl, project_path=None)


def _auto_save_callback():
"""Auto-save callback that runs after each command."""
global _auto_save, _session
if _auto_save and _session and _session.is_open and _session.is_modified:
# Don't auto-save if we're in REPL mode (user can explicitly save)
if not _repl_mode:
try:
_session.save_project()
click.echo(f"Auto-saved to: {_session.project_path}")
except Exception as e:
click.echo(f"Auto-save failed: {e}", err=True)


# ============================================================================
# Project commands
# ============================================================================
Expand Down