copy-to-frameio-watch
Copy to Frame.io Watch Folder: Zero-Click Client Upload Automation
The final step of every client delivery is the most tedious: taking the finished render from wherever DaVinci Resolve saved it and uploading it to Frame.io for review. This script eliminates the browser upload workflow entirely—select your renders in Finder, trigger the script, and Frame.io handles the upload automatically while you move on to the next task.
The Problem
I've automated the render workflow extensively with scripts like Quick Export and Render TV Export, but render automation only gets you halfway to delivery. After DaVinci Resolve finishes rendering, I still have to:
- Reveal the render in Finder (right-click → "Reveal in Finder")
- Open my browser
- Navigate to Frame.io
- Find the specific client project folder
- Drag the file into the Frame.io upload interface
- Wait for the upload to start (sometimes the drag-and-drop doesn't register)
- Close the browser tab
Total time: 30-45 seconds depending on how many browser tabs I have open, how fast Frame.io loads, and whether the drag-and-drop upload works on the first try.
This workflow is pure friction. I've already finished the creative work (editing, color, Fusion), and I've already automated the render. But I'm still manually shepherding files from Finder to Frame.io just to get them in front of my boss or client for review.
The cognitive overhead is worse than the time cost. After wrapping a project, I want to move immediately to the next timeline or start a different task. Having to context-switch to "now go upload this file to Frame.io" breaks my momentum.
The Solution
Frame.io's desktop app includes a watch folder feature: any file copied into a specific folder on your computer is automatically uploaded to a designated Frame.io project. This script automates the copy step:
- Finish rendering in DaVinci Resolve
- Reveal the render in Finder (or navigate to your render folder)
- Select the file(s) to upload (Cmd+A to select all renders)
- Cmd+Space → type "frame" → hit Enter (Raycast triggers the script)
- Script copies the selected files to the Frame.io watch folder
- Frame.io desktop app uploads the files automatically
- Boss/client receives an email notification that new files are ready for review
Total time: 2 seconds. No browser, no manual upload, no waiting for drag-and-drop to register.
The workflow is now:
- Render (automated with Quick Export or Render TV Export scripts)
- Upload (automated with this script)
- Move on to the next task
I don't think about Frame.io. The script handles it.
Technical Implementation
The script uses AppleScript to get the selected Finder files, then copies them to the Frame.io watch folder.
1. Watch Folder Setup
Frame.io's desktop app monitors a specific folder for new files:
WATCH_FOLDER="/Users/assistant2/Frame Watch Folder"
mkdir -p "$WATCH_FOLDER"
When the script runs, it ensures the watch folder exists (mkdir -p) even if it's the first time running the script. This prevents the copy from failing if the folder was accidentally deleted.
2. Pre-Upload Cleanup: Delete Old Files
Before copying new files, the script clears the watch folder:
rm -rf "$WATCH_FOLDER"/*
Why clear the folder first?
If I leave old files in the watch folder, Frame.io might re-upload them as duplicates (depending on how the app tracks "already uploaded" status). By clearing the folder first, I ensure only the newly copied files are uploaded.
This also prevents the watch folder from accumulating hundreds of old renders over time. Without cleanup, the folder would grow indefinitely, consuming disk space and cluttering the upload queue.
The rm -rf command deletes everything inside the watch folder (/*) but preserves the folder itself. This is safe because the watch folder is a staging area—files are copied here temporarily for upload, not stored long-term.
3. Getting Selected Finder Files
The script uses AppleScript to read the frontmost Finder selection:
FILE_PATH=$(osascript -e 'tell application "Finder" to set selectedItems to selection as alias list
if length of selectedItems is greater than 0 then
return POSIX path of (item 1 of selectedItems)
end if')
How this works:
tell application "Finder": Target the Finder appselection as alias list: Get all selected files as a listif length of selectedItems is greater than 0: Check if any files are selectedreturn POSIX path of (item 1 of selectedItems): Return the POSIX (Unix-style) path of the first selected file
If no files are selected in Finder, the script exits with an error message: "No file selected in Finder".
Note on multiple file selection:
While the script currently handles the first selected file (item 1), I typically select all renders I want to upload (Cmd+A in Finder after rendering), then trigger the script. For batch uploads, I run the script once per file or select each file individually. The watch folder approach means I can also just manually drag multiple files into the watch folder if needed, but the script optimizes for the single-file case (which is my most common workflow).
4. Copying to the Watch Folder
Once the script has the file path, it copies the file to the watch folder:
cp "$FILE_PATH" "$WATCH_FOLDER/"
cp (copy) duplicates the file—the original render stays in its output location (e.g., my DaVinci Resolve Renders folder), and a copy goes to the watch folder. This is safer than mv (move) because I preserve the original file in case Frame.io's upload fails or I need to re-upload later.
The Frame.io desktop app monitors the watch folder via filesystem events (using macOS's FSEvents API). The moment a new file appears, the app queues it for upload.
5. User Feedback
The script finishes by displaying the filename in Raycast's HUD:
FILENAME=$(basename "$FILE_PATH")
echo "Copied $FILENAME to Frame.io watch folder"
basename strips the directory path, leaving just the filename (My_Project_v3.mov instead of /Users/assistant2/DaVinci Resolve Renders/My_Project_v3.mov). This keeps the notification concise.
Raycast displays this as a brief notification at the top of the screen, confirming the upload was queued without interrupting my workflow.
Use Cases
Primary: Daily Client Review Workflow
I use this script daily (100+ times per week) for client deliverables at my 9-to-5:
- QuikTrip social content (15-30 second spots)
- AirCo commercial edits (30-60 second spots)
- Galaxy Home Recreation long-form content (5-10 minute videos)
After rendering a timeline, I reveal the file in Finder, trigger the script, and move on to the next edit. My boss receives an email notification from Frame.io within seconds, and review feedback comes back via Frame.io's comment system.
Secondary: Multi-Spot Deliveries
For broadcast projects with multiple spot lengths (15s, 30s, 60s versions), I:
- Use my Batch Render script to export all spot lengths
- Navigate to the render folder in Finder
- Cmd+A to select all renders
- Trigger this script once per file (or manually drag all files to the watch folder)
- Frame.io uploads all spots to the review folder
The boss reviews all versions in one session, leaving timestamped comments on each spot.
Why Not Just Drag Files to the Watch Folder Manually?
I could manually drag files from Finder to the watch folder, but that requires:
- Opening a second Finder window
- Navigating to the watch folder
- Dragging the file between windows
The script eliminates steps 1-3 by auto-copying selected files with a single keystroke. It's faster and requires less mental overhead—I don't have to remember where the watch folder lives or navigate to it.
Time Savings
Manual process (browser upload):
- Reveal render in Finder: 2 seconds
- Open browser, navigate to Frame.io: 5-10 seconds (depending on browser startup and load time)
- Find the correct project folder: 5-8 seconds (especially if working on multiple client projects)
- Drag file to Frame.io upload interface: 3-5 seconds
- Wait for upload to start: 2-5 seconds (sometimes drag-and-drop doesn't register)
- Close browser tab: 1 second
Total manual time: 18-31 seconds per file.
Automated process (watch folder script):
- Reveal render in Finder: 2 seconds
- Trigger script via Raycast: 1 second
- Script copies file to watch folder: <1 second
- Frame.io auto-uploads: 0 seconds of my time (happens in background)
Total automated time: 3 seconds (2 seconds if I'm already in the Finder window).
Savings per upload: 15-28 seconds.
At 5 client deliveries per day (conservative estimate for a busy production week), this saves 75-140 seconds (1.2-2.3 minutes) daily or 375-700 seconds (6.2-11.6 minutes) weekly.
But the real value is eliminating context switching. I no longer think about Frame.io uploads as a separate task. The script makes uploading feel like part of the render workflow—render finishes, trigger script, done.
Implementation Notes
This script requires:
- Frame.io desktop app (free download from Frame.io's website)
- Watch folder configured in the Frame.io app settings
- Raycast (for quick script triggering) or any command launcher
Setting Up Frame.io Watch Folder
To configure the Frame.io desktop app to monitor the watch folder:
- Install the Frame.io desktop app
- Open Frame.io → Preferences → Watch Folders
- Click "Add Watch Folder"
- Select the folder path (e.g.,
/Users/assistant2/Frame Watch Folder) - Choose the destination Frame.io project/folder where uploads should go
- Enable "Auto-upload" (uploads files immediately when they appear)
When the script copies a file to the watch folder, the Frame.io app uploads it to the designated project automatically.
Customizing the Watch Folder Path
To change the watch folder location, edit line 16:
WATCH_FOLDER="/Users/assistant2/Frame Watch Folder"
I keep the watch folder in my home directory (~) for easy access, but you can use any location (Desktop, Documents, external drive, etc.).
Handling Multiple File Selection
The script currently copies the first selected file (item 1 of selectedItems). To handle multiple files in a single run, you could modify the AppleScript to loop through all selected items:
osascript -e 'tell application "Finder"
set selectedItems to selection as alias list
repeat with anItem in selectedItems
set itemPath to POSIX path of anItem
do shell script "cp " & quoted form of itemPath & " /Users/assistant2/Frame\\ Watch\\ Folder/"
end repeat
end tell'
This would copy all selected files to the watch folder in one script execution. For now, I run the script once per file (or manually drag files if batch uploading), but the loop approach would streamline multi-file uploads.
Why cp Instead of mv?
The script uses cp (copy) instead of mv (move) to preserve the original render in its output location. This ensures:
- I have a backup if the Frame.io upload fails
- The render is still available in my DaVinci Resolve Renders folder for re-export or archival
- I can re-upload the file later without re-rendering
If you want to move files instead (deleting the original after copying to the watch folder), replace cp with mv:
mv "$FILE_PATH" "$WATCH_FOLDER/"
I recommend cp for safety—disk space is cheap, re-rendering is expensive.
Why This Matters
This script closes the gap between "render finished" and "client is reviewing." I've automated the render workflow extensively (Quick Export, Render TV Export, Batch Render), but without upload automation, I'd still be manually dragging files to Frame.io every time.
The watch folder approach is elegant because it decouples the upload mechanism from the script. The script's job is just "copy file to watch folder." The Frame.io app handles upload progress, retry logic, and error handling. If my internet drops mid-upload, Frame.io resumes automatically—I don't have to build retry logic into the script.
For anyone delivering client work via Frame.io, Dropbox, Google Drive, or similar platforms with watch folder support, this pattern is worth adopting. Automate the copy step, let the service handle the upload, and eliminate the browser-based manual upload workflow entirely.
The 15-28 second time savings per upload compounds quickly. At 5 uploads per day, this script saves 1-2 minutes daily. But more importantly, it removes decision fatigue and context switching. I don't think about Frame.io as a separate task—it's just part of the render workflow now.
And the pre-upload cleanup (rm -rf "$WATCH_FOLDER"/*) prevents duplicate uploads and disk space bloat. Without cleanup, the watch folder would accumulate hundreds of old renders over months. By clearing it before each copy, the folder stays lean and Frame.io only uploads new files.
This script shows the power of stacking automation on top of existing tools. Frame.io provides the watch folder, Raycast provides the launcher, AppleScript provides the Finder integration. The script is just 42 lines of glue code, but it eliminates an entire manual workflow.