feat: add step-by-step visual replay and harden process lifecycle

- UI: Implement dual-mode playback in FloatingVideoPlayer supporting video and step-by-step frame replay with scrub controls and auto-fallback
- Runtime: Prevent asyncio event loop hangs on Darwin and Linux by avoiding psutil.wait_procs on direct child processes
- Task Queue: Add worker exit watchdog and automatic recording recovery for completed or interrupted sessions
- Recording: Add ffmpeg ultrafast transcode fallback, shield recording finalization against cancellation, and handle on-the-fly MP4 conversion
- Docs: Polish README_CN styling and streamline flash runner agent prompt
This commit is contained in:
somew1nd committed 2026-08-26 00:53:24 -07:00
1 parent 06643e955b
commit a36a66ce6d
26 files changed
+1152 -117

No files matched your search

+15
View File
@@ -29,6 +29,7 @@ from artemis.sdk.types.task import AgentProfile
from artemis.utils.cli_helpers import display_device_status
from artemis.utils.logger import get_logger
from artemis.utils.video import check_ffmpeg_available
import signal
from rich.console import Console
from rich.panel import Panel
import typer
@@ -292,6 +293,15 @@ def run_command(
display_device_status(console, adb_client=adb_client)
cancelled = False
original_sigterm = None
try:
if hasattr(signal, "SIGTERM"):
original_sigterm = signal.signal(
signal.SIGTERM, lambda s, f: (_ for _ in ()).throw(KeyboardInterrupt())
)
except Exception:
pass
try:
asyncio.run(
execute_task(
@@ -335,5 +345,10 @@ def run_command(
console.print(f"[bold red]Task execution failed:[/bold red] {e}")
raise
finally:
try:
if original_sigterm is not None and hasattr(signal, "SIGTERM"):
signal.signal(signal.SIGTERM, original_sigterm)
except Exception:
pass
if cancelled:
raise SystemExit(130)