From 17a30ba82b70eb840a931f54a69df5315d744dd2 Mon Sep 17 00:00:00 2001 From: OpenClaw Date: Wed, 11 Mar 2026 02:52:33 +0800 Subject: [PATCH] fix(shotcut): add auto-save option for one-shot mode 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). --- .../cli_anything/shotcut/shotcut_cli.py | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/shotcut/agent-harness/cli_anything/shotcut/shotcut_cli.py b/shotcut/agent-harness/cli_anything/shotcut/shotcut_cli.py index 5cb11f2..2fa2f33 100755 --- a/shotcut/agent-harness/cli_anything/shotcut/shotcut_cli.py +++ b/shotcut/agent-harness/cli_anything/shotcut/shotcut_cli.py @@ -114,6 +114,7 @@ def wrapper(*args, **kwargs): _repl_mode = False +_auto_save = False # ============================================================================ @@ -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) @@ -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 # ============================================================================