Skip to content

LLM Agent Notice: A pure Markdown version formatted as a standard Agent Skill (SKILL.md) is available at https://ocelo.app/skills.md. For site overview, see https://ocelo.app/llms.txt.

Ocelo Agent Skill & Automation Reference

Ocelo is a native macOS app that captures a window or screen and exports a finished product video with smooth eased zooms, captions, cursor smoothing, and styling. The app bundle contains the same engine as a command-line interface designed for scripts and AI agents: single process, one take, one output file, machine-readable JSON on stdout.

There is no background server and nothing to install beyond the app itself.


1. Fast Reference & Binary Location

The binary lives inside the installed application bundle:

/Applications/Ocelo.app/Contents/MacOS/Ocelo --list-windows --json

Or from local development builds:

  • ./.build/release/Ocelo
  • $OCELO_BIN (if exported)

Two primary verbs exist:

  1. --list-windows: Query capturable windows, displays, or apps.
  2. --record: Record, edit, compose, and export in a single pass.

Running the binary without either flag opens the standard desktop GUI.


2. The Agent Execution Protocol

Autonomous agents driving Ocelo must follow this 5-step operational protocol to guarantee reliable takes:

[1. Pre-flight Check] ──> [2. Stage Subject] ──> [3. Roll & Sync on stderr] ──> [4. Drive Subject] ──> [5. Verify Export]
   --list-windows            Web / Native App       wait for "· recording"         AppleScript / CDP       ffmpeg frame check

Step 1: Pre-flight & TCC Permission Check

Screen Recording is a per-application macOS TCC permission. The CLI cannot grant it for itself. Run:

Ocelo --list-windows --json
  • Exit code 0: Permission granted. Proceed.
  • Exit code 3: Screen Recording not granted (ScreenCaptureKit reports empty content). Action required: Instruct the human user to open System Settings › Privacy & Security › Screen Recording and enable Ocelo (or the calling Terminal app).

Step 2: Stage the Subject (Apps vs. Websites)

  • Native macOS Apps: Use --launch "App Name" (or --launch /path/to/App.app) and --activate. Ocelo raises the window and re-reads its frame geometry, ensuring it is on the active macOS Space.
  • Websites: Open the URL in Chrome or Safari, size the window (e.g. 1380×860), and ensure the target tab is frontmost.

Step 3: Roll & Synchronize on stderr

Capturing is asynchronous. Never use a fixed sleep to guess when capture begins.

  1. Start Ocelo --record ... in the background with stderr redirected.
  2. Monitor stderr for the line:
    · recording <App> — <Title> for <seconds>s
  3. Only begin driving interactions after this line is emitted.

Step 4: Camera & Timing Rules

  • Explicit Zooms Required: Automatic zooms are triggered by real hardware clicks. Because agent-driven captures do not generate hardware clicks, the auto-zoom heuristic finds nothing. You must supply explicit --zooms.
  • The 1.5-Second Rule: The zoom parameter at specifies when the camera has completely settled on the crop. The camera path calculates an ease curve around at. Set at at least 1.5 seconds after the interaction or scroll finishes. Never zoom across an active page transition or fast scroll.
  • Coordinate Model: Coordinates u (horizontal) and v (vertical) are normalized fractions [0.0, 1.0] of the target window frame. $(0.0, 0.0)$ is top-left; $(0.5, 0.5)$ is dead center.

Step 5: Verification Loop

Never report success to the user without inspecting the output. Extract frames at key timestamps:

ffmpeg -y -ss 2.0 -i output.mp4 -frames:v 1 /tmp/beat-1.png
ffmpeg -y -ss 6.0 -i output.mp4 -frames:v 1 /tmp/beat-2.png

Inspect the images to verify that the target window was in focus, content was rendered, and no black frames or permission dialogues were recorded.


3. High-Level Automation Workflows

Ocelo provides ready-made scripts in its repository for orchestrating complex recordings without writing custom bash timing loops.

Workflow A: Declarative Storyboards (scripts/shoot.sh)

Shoots a complete multi-shot tour defined in a single JSON storyboard file. It handles browser staging over Chrome DevTools Protocol (CDP), native app launching, synchronization, and driver execution.

./scripts/shoot.sh docs/storyboards/tour.json out/tour.mp4

Storyboard Schema Example (Native App):

{
  "app": "Spotify",
  "lead": 1.5,
  "tail": 1.5,
  "shots": [
    {
      "label": "Next Track",
      "travel": 1.0,
      "hold": 3.0,
      "caption": "Skipping to next track via AppleScript",
      "zoom": { "u": 0.5, "v": 0.88, "scale": 1.8 },
      "pointer": { "u": 0.5, "v": 0.88, "travel": 0.8 },
      "actions": [
        { "at": 0.2, "type": "applescript", "script": "tell application \"Spotify\" to next track" }
      ]
    }
  ]
}

Storyboard Schema Example (Web Page):

{
  "url": "https://example.com",
  "width": 1440,
  "height": 900,
  "shots": [
    {
      "label": "Hero Section",
      "travel": 0.0,
      "hold": 3.5,
      "caption": "Welcome to Example",
      "zoom": { "u": 0.5, "v": 0.35, "scale": 1.6 }
    },
    {
      "label": "Feature Tour",
      "travel": 1.2,
      "hold": 4.0,
      "caption": "Integrated analytics",
      "zoom": { "u": 0.6, "v": 0.5, "scale": 2.0 }
    }
  ]
}

Workflow B: Web 1-Liner (scripts/record-site.sh)

A dedicated script for fast website showcases. It stages Chrome/Safari, resizes the browser to 1380×860, handles keyboard-based scrolling (Home, PageDown), and records with zooms and captions:

scripts/record-site.sh https://example.com \
  --seconds 12 \
  --captions '[{"at":0.5,"hold":3.0,"text":"Explore our new platform"}]'

4. Driving Targets: Native Apps vs. Websites

Subject Recommended Driving Technique Security / Permissions Required
Native Mac App (Scriptable) AppleScript (tell application "..." to ...) Standard macOS Automation dialog (prompted once per app)
Native Mac App (UI Controls) ocelo-drive or System Events key/click simulation macOS Accessibility permission
Website (Smooth scroll) Chrome DevTools Protocol (CDP) or window.scrollTo in JS Remote debugging port or browser developer menu
Website (Section jumps) System Events key codes (PageDown: 121, Home: 115) macOS Accessibility

[!TIP] Synthetic Mouse Scrolls Fail: macOS browsers silently ignore synthetic CGEvent mouse wheel events. When scrolling web pages, use keyboard key codes (PageDown / Home) or JavaScript execution (window.scrollTo({ top: ..., behavior: 'smooth' })).


5. Direct CLI Reference (Ocelo)

For custom pipelines, drive /Applications/Ocelo.app/Contents/MacOS/Ocelo directly.

--list-windows

List capturable targets in JSON format:

Ocelo --list-windows --json

Output:

{
  "windows": [
    {
      "id": "window-4465",
      "title": "Slack - General",
      "app": "Slack",
      "width": 1400,
      "height": 900,
      "kind": "window"
    }
  ]
}

--record Flags

Target Selection

Flag Description
--window <name> Window ID, app name, or title substring. Picks frontmost window if omitted.
--display Record the entire primary monitor instead of a window.
--launch <app> Launches the app (open -g -a), waits up to 10s for its window, then records. Implies --activate.
--activate Focuses and raises target window before recording, then recalculates window bounds. Recommended for correct $(u, v)$ coordinates.

Capture Settings

Flag Default Description
--seconds <n> 10 Total duration of the recording.
--fps <n> 60 Export frame rate.
--quality <q> full full, balanced, or small.
--settle <n> 0 (2.5 with --launch) Seconds to wait after the window appears before capture starts (avoids loading skeletons).
--countdown <n> 0 Seconds of pre-roll countdown.

Edit Specifications

All specs accept inline JSON or a file path reference @/path/to/spec.json.

  • Zooms (--zooms):

    [
      { "at": 2.0, "u": 0.5, "v": 0.4, "hold": 2.5, "scale": 2.0 }
    ]
    • at: Second in take when camera finishes easing and arrives at the crop target.
    • hold: Duration in seconds to stay magnified (default: 2.0).
    • scale: Magnification factor (default: 2.0).
    • u, v: Center coordinates as fractions of window width and height.
  • Captions (--captions):

    [
      { "at": 1.0, "hold": 3.0, "text": "Real-time sync enabled" }
    ]
  • Pointer (--pointer):

    [
      { "at": 1.5, "u": 0.5, "v": 0.5, "travel": 0.8 }
    ]

    Warps the system cursor smoothly over travel seconds. (Note: Pointer movement does not trigger mouse hover, click, or scroll events.)

Output Options

Flag Default Description
--out <path> recording.mp4 Destination file path.
--format <f> h264 h264, hevc, or gif.
--aspect <a> source source, 16:9, 4:3, 1:1, 9:16, or 4:5.
--max-width <n> 1920 Maximum pixel width of output video.
--no-alpha off Disables transparency pipeline. Always pass for opaque apps and browsers to use faster H.264 path.
--corner-radius <n> none Add rounded corners to the recorded window over background.
--json off Outputs metadata to stdout on completion.

6. Exit Codes Reference

Exit Code Cause Recommended Action
0 Success Verify exported file via ffmpeg.
2 Window list could not be read Check OS window server state.
3 Screen Recording permission denied Direct human user to System Settings › Privacy & Security › Screen Recording.
4 Target window not found Verify window title with Ocelo --list-windows --json. Check if app is on another Space.
5 Capture failed to initialize Check if display/window is valid and visible.
6 Capture failed during recording System sleep or target window closed mid-recording.
7 Video export / encoding failed Check destination directory write permissions and disk space.
8 --zooms JSON parse error Validate JSON syntax or use @path/to/file.json.
9 --pointer JSON parse error Validate JSON syntax.
10 --captions JSON parse error Validate JSON syntax.
11 --launch app failed to create window Increase --settle or inspect app launch status.

7. Complete Worked Example: Recording a Native App

Recording Spotify playing a song with an eased zoom on album art and an explanatory caption:

# 1. Start recording Spotify with a 10-second capture window
/Applications/Ocelo.app/Contents/MacOS/Ocelo --record \
  --window "Spotify" \
  --activate \
  --seconds 10 \
  --no-alpha \
  --zooms '[{"at": 3.0, "u": 0.15, "v": 0.85, "hold": 3.0, "scale": 2.2}]' \
  --captions '[{"at": 1.0, "hold": 3.5, "text": "Now Playing: Live Session"}]' \
  --out spotify-demo.mp4 \
  --json > result.json 2> progress.log &
RECORDER_PID=$!

# 2. Await sync point on stderr
while ! grep -q "recording " progress.log 2>/dev/null; do
  sleep 0.1
done

# 3. Trigger AppleScript action
osascript -e 'tell application "Spotify" to play track "spotify:track:4cOdK2wGLETKBW3PvgPWqT"'

# 4. Await process exit
wait $RECORDER_PID

# 5. Inspect result
cat result.json
ffmpeg -y -ss 3.0 -i spotify-demo.mp4 -frames:v 1 /tmp/spotify-verify.png